<!DOCTYPE html><html lang="zh-Hans"><head><meta charset="utf-8"><title>Angular - 多级注入器</title><meta name="Description" content="Angular is a platform for building mobile and desktop web applications.
    Join the community of millions of developers who build compelling user interfaces with Angular."><base href="/"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="search" type="application/opensearchdescription+xml" href="assets/opensearch.xml"><link rel="icon" type="image/x-icon" href="assets/images/favicons/favicon.ico"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-194x194.png" sizes="194x194"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-16x16.png" sizes="16x16"><link rel="apple-touch-icon" sizes="144x144" href="assets/images/favicons/favicon-144x144.png"><link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/images/favicons/favicon-144x144.png"><link href="assets/fonts/Material_Icons.css" rel="stylesheet"><link href="assets/fonts/Droid_Sans_Mono.css" rel="stylesheet"><link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"><link rel="manifest" href="pwa-manifest.json"><meta name="theme-color" content="#1976d2"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="translucent"><script async="" src="assets/js/analytics.js"></script><script>!function(e,a,n,t,s,c,g){e.GoogleAnalyticsObject=s,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(n),g=a.getElementsByTagName(n)[0],c.async=1,c.src="assets/js/analytics.js",~e.name.indexOf("NG_DEFER_BOOTSTRAP")||g.parentNode.insertBefore(c,g)}(window,document,"script",0,"ga")</script><script>window.onerror=function(){ga("send","exception",{exDescription:function(e,r,n,a,c){var l;e=e.replace(/^Error: /,""),l=c?c.stack.replace(/^Error: /,"").replace(e+"\n","").replace(/^ +/gm,"").replace(/^at /gm,"").replace(/(?: \(|@)http.+\/([^/)]+)\)?(?:\n|$)/gm,"@$1\n").replace(/ *\(eval code(:\d+:\d+)\)(?:\n|$)/gm,"@???$1\n"):r+":"+(n=n||"?")+":"+(a=a||"?");return(e+"\n"+l).substr(0,150)}.apply(null,arguments),exFatal:!0})}</script><link rel="stylesheet" href="styles.4adbe52ad34df01b5273.css"><style>.cdk-high-contrast-active .mat-toolbar{outline:solid 1px}.mat-toolbar-row,.mat-toolbar-single-row{display:flex;box-sizing:border-box;padding:0 16px;width:100%;flex-direction:row;align-items:center;white-space:nowrap}.mat-toolbar-multiple-rows{display:flex;box-sizing:border-box;flex-direction:column;width:100%}.mat-toolbar-multiple-rows{min-height:64px}.mat-toolbar-row,.mat-toolbar-single-row{height:64px}@media(max-width:599px){.mat-toolbar-multiple-rows{min-height:56px}.mat-toolbar-row,.mat-toolbar-single-row{height:56px}}</style><style>.mat-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px}.mat-icon.mat-icon-inline{font-size:inherit;height:inherit;line-height:inherit;width:inherit}[dir=rtl] .mat-icon-rtl-mirror{transform:scale(-1,1)}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon{display:block}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-icon{margin:auto}</style><style>.mat-button .mat-button-focus-overlay,.mat-icon-button .mat-button-focus-overlay{opacity:0}.mat-button:hover .mat-button-focus-overlay,.mat-stroked-button:hover .mat-button-focus-overlay{opacity:.04}@media(hover:none){.mat-button:hover .mat-button-focus-overlay,.mat-stroked-button:hover .mat-button-focus-overlay{opacity:0}}.mat-button,.mat-flat-button,.mat-icon-button,.mat-stroked-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible}.mat-button::-moz-focus-inner,.mat-flat-button::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-stroked-button::-moz-focus-inner{border:0}.mat-button[disabled],.mat-flat-button[disabled],.mat-icon-button[disabled],.mat-stroked-button[disabled]{cursor:default}.mat-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-button.cdk-program-focused .mat-button-focus-overlay,.mat-flat-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-flat-button.cdk-program-focused .mat-button-focus-overlay,.mat-icon-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-icon-button.cdk-program-focused .mat-button-focus-overlay,.mat-stroked-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-stroked-button.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-button::-moz-focus-inner,.mat-flat-button::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-stroked-button::-moz-focus-inner{border:0}.mat-raised-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1)}.mat-raised-button::-moz-focus-inner{border:0}.mat-raised-button[disabled]{cursor:default}.mat-raised-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-raised-button.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-raised-button::-moz-focus-inner{border:0}._mat-animation-noopable.mat-raised-button{transition:none;animation:none}.mat-stroked-button{border:1px solid currentColor;padding:0 15px;line-height:34px}.mat-stroked-button .mat-button-focus-overlay,.mat-stroked-button .mat-button-ripple.mat-ripple{top:-1px;left:-1px;right:-1px;bottom:-1px}.mat-fab{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);min-width:0;border-radius:50%;width:56px;height:56px;padding:0;flex-shrink:0}.mat-fab::-moz-focus-inner{border:0}.mat-fab[disabled]{cursor:default}.mat-fab.cdk-keyboard-focused .mat-button-focus-overlay,.mat-fab.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-fab::-moz-focus-inner{border:0}._mat-animation-noopable.mat-fab{transition:none;animation:none}.mat-fab .mat-button-wrapper{padding:16px 0;display:inline-block;line-height:24px}.mat-mini-fab{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);min-width:0;border-radius:50%;width:40px;height:40px;padding:0;flex-shrink:0}.mat-mini-fab::-moz-focus-inner{border:0}.mat-mini-fab[disabled]{cursor:default}.mat-mini-fab.cdk-keyboard-focused .mat-button-focus-overlay,.mat-mini-fab.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-mini-fab::-moz-focus-inner{border:0}._mat-animation-noopable.mat-mini-fab{transition:none;animation:none}.mat-mini-fab .mat-button-wrapper{padding:8px 0;display:inline-block;line-height:24px}.mat-icon-button{padding:0;min-width:0;width:40px;height:40px;flex-shrink:0;line-height:40px;border-radius:50%}.mat-icon-button .mat-icon,.mat-icon-button i{line-height:24px}.mat-button-focus-overlay,.mat-button-ripple.mat-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;border-radius:inherit}.mat-button-ripple.mat-ripple:not(:empty){transform:translateZ(0)}.mat-button-focus-overlay{opacity:0;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1)}._mat-animation-noopable .mat-button-focus-overlay{transition:none}.cdk-high-contrast-active .mat-button-focus-overlay{background-color:#fff}.cdk-high-contrast-black-on-white .mat-button-focus-overlay{background-color:#000}.mat-button-ripple-round{border-radius:50%;z-index:1}.mat-button .mat-button-wrapper>*,.mat-fab .mat-button-wrapper>*,.mat-flat-button .mat-button-wrapper>*,.mat-icon-button .mat-button-wrapper>*,.mat-mini-fab .mat-button-wrapper>*,.mat-raised-button .mat-button-wrapper>*,.mat-stroked-button .mat-button-wrapper>*{vertical-align:middle}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button{display:block;font-size:inherit;width:2.5em;height:2.5em}.cdk-high-contrast-active .mat-button,.cdk-high-contrast-active .mat-fab,.cdk-high-contrast-active .mat-flat-button,.cdk-high-contrast-active .mat-icon-button,.cdk-high-contrast-active .mat-mini-fab,.cdk-high-contrast-active .mat-raised-button{outline:solid 1px}</style><style>.mat-drawer-container{position:relative;z-index:1;box-sizing:border-box;-webkit-overflow-scrolling:touch;display:block;overflow:hidden}.mat-drawer-container[fullscreen]{top:0;left:0;right:0;bottom:0;position:absolute}.mat-drawer-container[fullscreen].mat-drawer-container-has-open{overflow:hidden}.mat-drawer-container.mat-drawer-container-explicit-backdrop .mat-drawer-side{z-index:3}.mat-drawer-container.ng-animate-disabled .mat-drawer-backdrop,.mat-drawer-container.ng-animate-disabled .mat-drawer-content,.ng-animate-disabled .mat-drawer-container .mat-drawer-backdrop,.ng-animate-disabled .mat-drawer-container .mat-drawer-content{transition:none}.mat-drawer-backdrop{top:0;left:0;right:0;bottom:0;position:absolute;display:block;z-index:3;visibility:hidden}.mat-drawer-backdrop.mat-drawer-shown{visibility:visible}.mat-drawer-transition .mat-drawer-backdrop{transition-duration:.4s;transition-timing-function:cubic-bezier(.25,.8,.25,1);transition-property:background-color,visibility}.cdk-high-contrast-active .mat-drawer-backdrop{opacity:.5}.mat-drawer-content{position:relative;z-index:1;display:block;height:100%;overflow:auto}.mat-drawer-transition .mat-drawer-content{transition-duration:.4s;transition-timing-function:cubic-bezier(.25,.8,.25,1);transition-property:transform,margin-left,margin-right}.mat-drawer{position:relative;z-index:4;display:block;position:absolute;top:0;bottom:0;z-index:3;outline:0;box-sizing:border-box;overflow-y:auto;transform:translate3d(-100%,0,0)}.cdk-high-contrast-active .mat-drawer,.cdk-high-contrast-active [dir=rtl] .mat-drawer.mat-drawer-end{border-right:solid 1px currentColor}.cdk-high-contrast-active .mat-drawer.mat-drawer-end,.cdk-high-contrast-active [dir=rtl] .mat-drawer{border-left:solid 1px currentColor;border-right:none}.mat-drawer.mat-drawer-side{z-index:2}.mat-drawer.mat-drawer-end{right:0;transform:translate3d(100%,0,0)}[dir=rtl] .mat-drawer{transform:translate3d(100%,0,0)}[dir=rtl] .mat-drawer.mat-drawer-end{left:0;right:auto;transform:translate3d(-100%,0,0)}.mat-drawer-inner-container{width:100%;height:100%;overflow:auto;-webkit-overflow-scrolling:touch}.mat-sidenav-fixed{position:fixed}</style><style>.nav-link.highlight[_ngcontent-ng-docs-c30]{color:#ff0}</style><style>.mat-progress-bar{display:block;height:4px;overflow:hidden;position:relative;transition:opacity 250ms linear;width:100%}._mat-animation-noopable.mat-progress-bar{transition:none;animation:none}.mat-progress-bar .mat-progress-bar-element,.mat-progress-bar .mat-progress-bar-fill::after{height:100%;position:absolute;width:100%}.mat-progress-bar .mat-progress-bar-background{width:calc(100% + 10px)}.cdk-high-contrast-active .mat-progress-bar .mat-progress-bar-background{display:none}.mat-progress-bar .mat-progress-bar-buffer{transform-origin:top left;transition:transform 250ms ease}.cdk-high-contrast-active .mat-progress-bar .mat-progress-bar-buffer{border-top:solid 5px;opacity:.5}.mat-progress-bar .mat-progress-bar-secondary{display:none}.mat-progress-bar .mat-progress-bar-fill{animation:none;transform-origin:top left;transition:transform 250ms ease}.cdk-high-contrast-active .mat-progress-bar .mat-progress-bar-fill{border-top:solid 4px}.mat-progress-bar .mat-progress-bar-fill::after{animation:none;content:"";display:inline-block;left:0}.mat-progress-bar[dir=rtl],[dir=rtl] .mat-progress-bar{transform:rotateY(180deg)}.mat-progress-bar[mode=query]{transform:rotateZ(180deg)}.mat-progress-bar[mode=query][dir=rtl],[dir=rtl] .mat-progress-bar[mode=query]{transform:rotateZ(180deg) rotateY(180deg)}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-fill,.mat-progress-bar[mode=query] .mat-progress-bar-fill{transition:none}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary,.mat-progress-bar[mode=query] .mat-progress-bar-primary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-translate 2s infinite linear;left:-145.166611%}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-primary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary,.mat-progress-bar[mode=query] .mat-progress-bar-secondary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-translate 2s infinite linear;left:-54.888891%;display:block}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-secondary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=buffer] .mat-progress-bar-background{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-background-scroll 250ms infinite linear;display:block}.mat-progress-bar._mat-animation-noopable .mat-progress-bar-background,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-buffer,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-fill,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-fill::after,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-primary,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-primary.mat-progress-bar-fill::after,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-secondary,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-secondary.mat-progress-bar-fill::after{animation:none;transition:none}@keyframes mat-progress-bar-primary-indeterminate-translate{0%{transform:translateX(0)}20%{animation-timing-function:cubic-bezier(.5,0,.701732,.495819);transform:translateX(0)}59.15%{animation-timing-function:cubic-bezier(.302435,.381352,.55,.956352);transform:translateX(83.67142%)}100%{transform:translateX(200.611057%)}}@keyframes mat-progress-bar-primary-indeterminate-scale{0%{transform:scaleX(.08)}36.65%{animation-timing-function:cubic-bezier(.334731,.12482,.785844,1);transform:scaleX(.08)}69.15%{animation-timing-function:cubic-bezier(.06,.11,.6,1);transform:scaleX(.661479)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-secondary-indeterminate-translate{0%{animation-timing-function:cubic-bezier(.15,0,.515058,.409685);transform:translateX(0)}25%{animation-timing-function:cubic-bezier(.31033,.284058,.8,.733712);transform:translateX(37.651913%)}48.35%{animation-timing-function:cubic-bezier(.4,.627035,.6,.902026);transform:translateX(84.386165%)}100%{transform:translateX(160.277782%)}}@keyframes mat-progress-bar-secondary-indeterminate-scale{0%{animation-timing-function:cubic-bezier(.15,0,.515058,.409685);transform:scaleX(.08)}19.15%{animation-timing-function:cubic-bezier(.31033,.284058,.8,.733712);transform:scaleX(.457104)}44.15%{animation-timing-function:cubic-bezier(.4,.627035,.6,.902026);transform:scaleX(.72796)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-background-scroll{to{transform:translateX(-8px)}}</style><script charset="utf-8" src="toc-toc-module-es2015.f8531f591ee147aebcc6.js"></script><script charset="utf-8" src="default~code-code-example-module~code-code-tabs-module-es2015.9efcc76d2979a2e605e0.js"></script><script charset="utf-8" src="code-code-example-module-es2015.fa05e6f700453813d256.js"></script><script charset="utf-8" src="live-example-live-example-module-es2015.d3b124043392e69f9e97.js"></script><script charset="utf-8" src="assets-js-prettify-js-es2015.ba856648f2dd2d930a9b.js"></script></head><body><aio-shell ng-version="9.0.0-rc.11" class="aio-notification-hide folder-guide mode-stable page-guide-hierarchical-dependency-injection sidenav-open view-SideNav"><div id="top-of-page"></div><mat-toolbar color="primary" class="mat-toolbar app-toolbar no-print mat-primary mat-toolbar-multiple-rows"><mat-toolbar-row class="mat-toolbar-row notification-container"><aio-notification notificationid="survey-february-2019" expirationdate="2019-03-01" class="ng-tns-c22-0 ng-trigger ng-trigger-hideAnimation" style="height:0"><span class="content ng-tns-c22-0"><a href="http://bit.ly/angular-survey-2019" target="_blank" class="ng-tns-c22-0"><mat-icon role="img" svgicon="insert_comment" aria-label="Announcement" class="mat-icon notranslate icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></mat-icon><span class="message"><b>填写这份《一分钟调查》</b>，帮我们（开发组）做得更好！</span><span class="action-button">去填写</span></a></span><button mat-icon-button="" aria-label="Close" class="close-button ng-tns-c22-0 mat-icon-button mat-button-base"><span class="mat-button-wrapper"><mat-icon role="img" svgicon="close" aria-label="Dismiss notification" class="mat-icon notranslate mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></mat-icon></span><div matripple="" class="mat-ripple mat-button-ripple mat-button-ripple-round"></div><div class="mat-button-focus-overlay"></div></button></aio-notification></mat-toolbar-row><mat-toolbar-row class="mat-toolbar-row"><button mat-button="" title="Docs menu" class="hamburger mat-button mat-button-base"><span class="mat-button-wrapper"><mat-icon role="img" svgicon="menu" class="mat-icon notranslate mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></svg></mat-icon></span><div matripple="" class="mat-ripple mat-button-ripple"></div><div class="mat-button-focus-overlay"></div></button><a href="/" class="nav-link home"><img src="assets/images/logos/angular/logo-nav@2x.png" width="150" height="40" title="Home" alt="Home" class="ng-star-inserted"></a><aio-top-menu _nghost-ng-docs-c30="" class="ng-star-inserted"><ul _ngcontent-ng-docs-c30="" role="navigation"><li _ngcontent-ng-docs-c30="" class="ng-star-inserted"><a _ngcontent-ng-docs-c30="" class="nav-link" href="features" title="特性" target="_self"><span _ngcontent-ng-docs-c30="" class="nav-link-inner">特性</span></a></li><li _ngcontent-ng-docs-c30="" class="ng-star-inserted"><a _ngcontent-ng-docs-c30="" class="nav-link" href="docs" title="文档" target="_self"><span _ngcontent-ng-docs-c30="" class="nav-link-inner">文档</span></a></li><li _ngcontent-ng-docs-c30="" class="ng-star-inserted"><a _ngcontent-ng-docs-c30="" class="nav-link" href="resources" title="资源" target="_self"><span _ngcontent-ng-docs-c30="" class="nav-link-inner">资源</span></a></li><li _ngcontent-ng-docs-c30="" class="ng-star-inserted"><a _ngcontent-ng-docs-c30="" class="nav-link" href="events" title="会议" target="_self"><span _ngcontent-ng-docs-c30="" class="nav-link-inner">会议</span></a></li><li _ngcontent-ng-docs-c30="" class="ng-star-inserted"><a _ngcontent-ng-docs-c30="" class="nav-link" href="https://blog.wangke.io/" title="译者汪志成的博客，包括翻译文章和原创文章" target="_blank"><span _ngcontent-ng-docs-c30="" class="nav-link-inner">译者博客</span></a></li><li _ngcontent-ng-docs-c30="" class="ng-star-inserted"><a _ngcontent-ng-docs-c30="" class="nav-link" href="translations/cn/home" title="关于中文版" target="_self"><span _ngcontent-ng-docs-c30="" class="nav-link-inner">关于中文版</span></a></li></ul></aio-top-menu><aio-search-box class="search-container"><input type="search" aria-label="search" placeholder="搜索"></aio-search-box><div class="toolbar-external-icons-container"><a href="https://twitter.com/angular" title="Twitter" aria-label="Angular on twitter"><mat-icon role="img" svgicon="logos:twitter" class="mat-icon notranslate mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 50 59" xmlns="http://www.w3.org/2000/svg"><path d="M50,9.3c-1.8,0.8-3.8,1.4-5.9,1.6c2.1-1.3,3.7-3.3,4.5-5.7c-2,1.2-4.2,2-6.5,2.5c-1.9-2-4.5-3.2-7.5-3.2c-5.7,0-10.3,4.6-10.3,10.3c0,0.8,0.1,1.6,0.3,2.3C16.1,16.7,8.5,12.6,3.5,6.4c-0.9,1.5-1.4,3.3-1.4,5.2c0,3.6,1.8,6.7,4.6,8.5C5,20,3.4,19.6,2,18.8c0,0,0,0.1,0,0.1c0,5,3.5,9.1,8.2,10.1c-0.9,0.2-1.8,0.4-2.7,0.4c-0.7,0-1.3-0.1-1.9-0.2c1.3,4.1,5.1,7,9.6,7.1c-3.5,2.8-7.9,4.4-12.7,4.4c-0.8,0-1.6,0-2.4-0.1c4.5,2.9,9.9,4.6,15.7,4.6c18.9,0,29.2-15.6,29.2-29.2c0-0.4,0-0.9,0-1.3C46.9,13.2,48.6,11.4,50,9.3z"></path></svg></mat-icon></a><a href="https://github.com/angular/angular" title="GitHub" aria-label="Angular on github"><mat-icon role="img" svgicon="logos:github" class="mat-icon notranslate mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 51.8 50.4" xmlns="http://www.w3.org/2000/svg"><path d="M25.9,0.2C11.8,0.2,0.3,11.7,0.3,25.8c0,11.3,7.3,20.9,17.5,24.3c1.3,0.2,1.7-0.6,1.7-1.2c0-0.6,0-2.6,0-4.8c-7.1,1.5-8.6-3-8.6-3c-1.2-3-2.8-3.7-2.8-3.7c-2.3-1.6,0.2-1.6,0.2-1.6c2.6,0.2,3.9,2.6,3.9,2.6c2.3,3.9,6,2.8,7.5,2.1c0.2-1.7,0.9-2.8,1.6-3.4c-5.7-0.6-11.7-2.8-11.7-12.7c0-2.8,1-5.1,2.6-6.9c-0.3-0.7-1.1-3.3,0.3-6.8c0,0,2.1-0.7,7,2.6c2-0.6,4.2-0.9,6.4-0.9c2.2,0,4.4,0.3,6.4,0.9c4.9-3.3,7-2.6,7-2.6c1.4,3.5,0.5,6.1,0.3,6.8c1.6,1.8,2.6,4.1,2.6,6.9c0,9.8-6,12-11.7,12.6c0.9,0.8,1.7,2.4,1.7,4.7c0,3.4,0,6.2,0,7c0,0.7,0.5,1.5,1.8,1.2c10.2-3.4,17.5-13,17.5-24.3C51.5,11.7,40.1,0.2,25.9,0.2z"></path></svg></mat-icon></a></div></mat-toolbar-row></mat-toolbar><mat-sidenav-container role="main" class="mat-drawer-container mat-sidenav-container sidenav-container mat-drawer-transition has-floating-toc"><div class="mat-drawer-backdrop ng-star-inserted"></div><div class="cdk-visually-hidden cdk-focus-trap-anchor" aria-hidden="true"></div><mat-sidenav tabindex="-1" class="mat-drawer mat-sidenav sidenav ng-tns-c18-1 ng-trigger ng-trigger-transform mat-drawer-side ng-star-inserted mat-drawer-opened" style="transform:none;visibility:visible"><div class="mat-drawer-inner-container ng-tns-c18-1"><aio-nav-menu class="ng-tns-c18-1"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="docs" title="Angular 文档简介" target="_self"><span>简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 collapsed ng-star-inserted" title="通过构建第一个 Angular 应用来学习基础知识" aria-pressed="false"><span>快速上手</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="start" title="介绍 Angular 的组件模型、模板语法和组件通讯" target="_self"><span>你的第一个应用</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="start/routing" title="介绍如何使用浏览器的 URL 在组件之间进行路由" target="_self"><span>路由</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="start/data" title="介绍服务以及如何访问外部数据" target="_self"><span>管理数据</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="start/forms" title="学习如何使用表单从用户那里获取并管理数据" target="_self"><span>表单</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="start/deployment" title="通过你的应用放到 Firebase 或自己的服务器上来把它分享给外界" target="_self"><span>部署</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="guide/setup-local" title="使用 Angular CLI 搭建本地开发环境简介" target="_self"><span>搭建环境</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 expanded selected ng-star-inserted" title="Angular 的基本原理" aria-pressed="true"><span>基本原理</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 expanded selected"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="介绍 Angular 应用中的一些基本概念。" aria-pressed="false"><span>Angular 的基本概念</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture" title="Angular 应用中的基本构造块。" target="_self"><span>基本概念简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-modules" title="关于 Angular 模块（NgModules）。" target="_self"><span>模块简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-components" title="关于组件、模板和视图。" target="_self"><span>组件简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-services" title="关于服务与依赖注入。" target="_self"><span>服务与 DI 简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-next-steps" title="超越基础阶段。" target="_self"><span>后续步骤</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="英雄指南是这里大量 Angular 范例的基础" aria-pressed="false"><span>英雄指南</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial" title="《英雄指南》教程简介" target="_self"><span>简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt0" title="创建应用的外壳" target="_self"><span>应用的“外壳”</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt1" title="第一部分：构建一个简单的英雄编辑器" target="_self"><span>1. 英雄编辑器</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt2" title="第二部分：构建一个主从结构的页面，用于展现英雄列表。" target="_self"><span>2. 显示英雄列表</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt3" title="第三部分：把主从结构的视图重构成几个独立的组件。" target="_self"><span>3. 创建特性组件</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt4" title="第四部分：创建一个可复用的服务来管理英雄数据。" target="_self"><span>4. 添加服务</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt5" title="第五部分：添加 Angular 路由器，并且学习在视图之间导航。" target="_self"><span>5. 添加应用内导航</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt6" title="第六部分：通过 HTTP 来获取并保存英雄数据。" target="_self"><span>6. 从服务器获取数据</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="通过数据绑定构建动态视图" aria-pressed="false"><span>组件与模板</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/displaying-data" title="属性绑定可以帮助应用把数据显示在界面上" target="_self"><span>显示数据</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/template-syntax" title="学习如何写模板，以便借助数据绑定机制显示数据并响应事件。" target="_self"><span>模板语法</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/user-input" title="用户输入会触发 DOM 事件。Angular 会通过事件绑定来监听那些事件，并把修改后的值传回应用的组件和模型中。" target="_self"><span>用户输入</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/lifecycle-hooks" title="Angular 调用指令和组件的生命周期钩子函数，包括它的创建、变更和销毁时。" target="_self"><span>生命周期钩子</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/component-interaction" title="在不同的指令和组件之间共享信息" target="_self"><span>组件交互</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/component-styles" title="添加专属于某个组件的样式" target="_self"><span>组件样式</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dynamic-component-loader" title="动态加载组件" target="_self"><span>动态组件</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/elements" title="把组件转换成自定义元素" target="_self"><span>Angular 元素</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/attribute-directives" title="属性型指令把行为添加到现有元素上。" target="_self"><span>属性型指令</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/structural-directives" title="结构型指令可以操纵页面的布局" target="_self"><span>结构型指令</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/pipes" title="管道可以在模板中转换显示的内容。" target="_self"><span>管道</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="Angular 的表单" aria-pressed="false"><span>表单</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/forms-overview" title="表单可以创建集中、高效、引人注目的输入体验。Angular 表单可以协调一组数据绑定控件，跟踪变更，验证输入，并表达错误信息。" target="_self"><span>简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/reactive-forms" title="使用 FormBuilder、表单组和表单数组创建响应式表单。" target="_self"><span>响应式表单</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/forms" title="使用指令和 Angular 模板语法创建模板驱动表单。" target="_self"><span>模板驱动表单</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/form-validation" title="验证用户的表单输入" target="_self"><span>表单验证</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dynamic-form" title="使用 FormGroup 渲染动态表单。" target="_self"><span>动态表单</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="Observable 与 RxJS" aria-pressed="false"><span>Observable 与 RxJS</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/observables" title="" target="_self"><span>可观察对象(Observable)</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/rx-library" title="" target="_self"><span>RxJS 库</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/observables-in-angular" title="" target="_self"><span>Angular 中的可观察对象</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/practical-observable-usage" title="" target="_self"><span>用法实战</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/comparing-observables" title="" target="_self"><span>与其它技术的比较</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="Angular 中的模块" aria-pressed="false"><span>NgModules</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodules" title="使用 NgModule 让你的应用更高效" target="_self"><span>NgModule 简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-vs-jsmodule" title="JavaScript 模块和 NgModule 之间的差异" target="_self"><span>JS 模块 vs NgModule</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/bootstrapping" title="告诉 Angular 如何在根 &quot;AppModule&quot; 中构造和引导应用。" target="_self"><span>应用的根模块</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/frequent-ngmodules" title="介绍最常用的 NgModule" target="_self"><span>常用模块</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/module-types" title="介绍特性模块的几种类型" target="_self"><span>特性模块的分类</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/entry-components" title="关于 Angular 中入口组件的一切" target="_self"><span>入口组件</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/feature-modules" title="创建特性模块，以组织你的代码" target="_self"><span>特性模块</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/providers" title="服务提供者与 NgModule" target="_self"><span>服务提供者</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/singleton-services" title="创建单例服务" target="_self"><span>单例服务</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/lazy-loading-ngmodules" title="惰性加载模块，以提高应用的性能" target="_self"><span>惰性加载的特性模块</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/sharing-ngmodules" title="共享 NgModule 让你的应用现代化。" target="_self"><span>共享 NgModule</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-api" title="理解 NgModule 的那些细节。" target="_self"><span>NgModule API</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-faq" title="回答关于 NgModules 的常见问题。" target="_self"><span>NgModule 常见问题</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 expanded selected ng-star-inserted" title="依赖注入：创建并注入各种服务。" aria-pressed="true"><span>依赖注入</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 expanded selected"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection" title="Angular 的依赖注入系统能够为 Angular 创建的类创建并交付它们所依赖的服务。" target="_self"><span>Angular 依赖注入</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 expanded selected ng-star-inserted" style="position:relative" href="guide/hierarchical-dependency-injection" title="与组件树平行的注入器树，并支持嵌套的依赖。" target="_self"><span>多级注入器</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-providers" title="各种提供者类型的更多知识。" target="_self"><span>DI 提供者</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-in-action" title="依赖注入的使用技巧" target="_self"><span>DI 实战</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-navtree" title="使用注入器树来查找父组件。" target="_self"><span>浏览组件树</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/http" title="通过 HTTP 协议与远程服务器对话。" target="_self"><span>HttpClient</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/router" title="揭示如何通过 Angular 路由进行基本的屏幕导航。" target="_self"><span>路由与导航</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="Angular 动画系统指南" aria-pressed="false"><span>动画</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/animations" title="Angular 动画的基础技术。" target="_self"><span>简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/transition-and-triggers" title="转场与触发器的高级技术。" target="_self"><span>转场与触发器</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/complex-animation-sequences" title="复杂的 Angular 动画序列。" target="_self"><span>复杂序列</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/reusable-animations" title="创建可复用的动画。" target="_self"><span>可复用动画</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/route-animations" title="为路由提供转场动画。" target="_self"><span>路由转场动画</span></a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 collapsed ng-star-inserted" title="把 Angular 用到你的实际工作中的一些技巧" aria-pressed="false"><span>其它技术</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/security" title="Angular 应用开发中的安全技术。" target="_self"><span>安全</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/i18n" title="把应用模板中的文本翻译成多种语言。" target="_self"><span>国际化（i18n）</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/accessibility" title="设计能被所有用户访问的应用" target="_self"><span>无障碍（a11y）</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="Angular Service Worker: 控制应用资源的缓存。" aria-pressed="false"><span>Service Worker 与 PWA</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-intro" title="Angular 对 Service Worker 的实现提升了慢速或不稳定的网络连接下的用户体验。" target="_self"><span>简介</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-getting-started" title="在 CLI 项目中启用 Service Worker，并在浏览器中查看效果。" target="_self"><span>快速上手</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/app-shell" title="在 CLI 项目中启用应用外壳。" target="_self"><span>应用外壳</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-communications" title="那些能让你和 Angular 的 Service Worker 通讯的服务类。" target="_self"><span>与 Service Worker 通讯</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-devops" title="使用 Service Worker 运行应用、管理应用更新、调试以及杀掉正在运行的应用。" target="_self"><span>生产环境下的 Service Worker</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-config" title="配置 Service Worker 的缓存行为。" target="_self"><span>Service Worker 配置</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/universal" title="使用 Angular Universal 在服务端渲染 HTML。" target="_self"><span>服务端渲染</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="把 AngularJS 应用增量式的升级到 Angular。" aria-pressed="false"><span>从 AngularJS 升级</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/upgrade" title="把 AngularJS 应用增量式的升级到 Angular。" target="_self"><span>升级步骤</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/upgrade-performance" title="用更灵活的方式把 AngularJS 升级到 Angular。" target="_self"><span>更关注性能的升级方式</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ajs-quick-reference" title="学习如何把 AngularJS 的概念映射到 Angular 中。" target="_self"><span>AngularJS 与 Angular 的概念对照</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="使用共享库扩展 Angular" aria-pressed="false"><span>开发 Angular 库</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/libraries" title="理解何时以及如何使用和创建库。" target="_self"><span>库概览</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/using-libraries" title="把已发布的库集成进你的应用中。" target="_self"><span>使用已发布的库</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/creating-libraries" title="通过创建、发布和使用你自己的库来扩展 Angular。" target="_self"><span>创建库</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="理解原理图" aria-pressed="false"><span>原理图（Schematic）</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/schematics" title="理解 Angular 如何使用原理图。" target="_self"><span>原理图概览</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/schematics-authoring" title="理解原理图的结构。" target="_self"><span>制作原理图</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/schematics-for-libraries" title="使用原理图来把你的库集成进 Angular CLI 中。" target="_self"><span>库的原理图</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/cli-builder" title="使用构建器定制 Angular CLI。" target="_self"><span>CLI 构建器</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/web-worker" title="在 Angular CLI 中使用 Web Worker。" target="_self"><span>Web Worker</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 collapsed ng-star-inserted" title="关于构建、测试和部署的信息" aria-pressed="false"><span>开发工作流</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="理解 AOT 预先编译器。" aria-pressed="false"><span>AOT 预先编译器</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/aot-compiler" title="学习为何以及如何使用预先编译器。" target="_self"><span>预先编译</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/angular-compiler-options" title="配置 AOT 编译。" target="_self"><span>Angular 编译器选项</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/aot-metadata-errors" title="解决 AOT 编译错误。" target="_self"><span>AOT 元数据错误</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/template-typecheck" title="Angular 中的模板类型检查。" target="_self"><span>模板类型检查</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/build" title="构建应用及为应用启动开发服务器。" target="_self"><span>构建与运行</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/bazel" title="如何配置你的环境，以利用 Bazel 进行构建和测试。" target="_self"><span>使用 Bazel 进行构建</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/testing" title="测试 Angular 应用的技巧与实践。" target="_self"><span>测试</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/deployment" title="了解如何部署 Angular 应用。" target="_self"><span>发布</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-2 collapsed ng-star-inserted" title="与开发环境和工具集成起来" aria-pressed="false"><span>开发工具集成</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/language-service" title="使用 Angular 语言服务加速开发。" target="_self"><span>语言服务</span></a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 collapsed ng-star-inserted" title="工作空间与项目的结构，及其配置文件。" aria-pressed="false"><span>配置</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/file-structure" title="Angular 工作区在文件系统中是怎样的。" target="_self"><span>项目文件结构</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/workspace-config" title="&quot;angular.json&quot; 包含供 CLI 命令使用的工作区和项目默认配置。" target="_self"><span>工作区配置</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/npm-packages" title="开发期间和运行期间所需的 npm 包的说明。" target="_self"><span>npm 包</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/typescript-configuration" title="给 Angular 开发者的 TypeScript 配置。" target="_self"><span>TypeScript 配置</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/browser-support" title="浏览器支持与腻子脚本指南。" target="_self"><span>浏览器支持</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 collapsed ng-star-inserted" title="Angular 的版本发布实践、更新与升级。" aria-pressed="false"><span>发布信息</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/updating" title="如何把 Angular 应用和库升级到最新版本。" target="_self"><span>保持最新</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/releases" title="Angular 的版本、发布、支持、弃用策略及实践。" target="_self"><span>发布实践</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/updating-to-version-9" title="支持把你的应用从 8 升级到 9。" target="_self"><span>升级到第 9 版</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/deprecations" title="弃用的 Angular API 和特性汇总。" target="_self"><span>弃用清单</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/ivy" title="关于 Angular Ivy 的编译与渲染管道。" target="_self"><span>Angular Ivy</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 collapsed ng-star-inserted" title="Angular 语法、编码、术语汇总。" aria-pressed="false"><span>快捷手册</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/cheatsheet" title="关于 Angular 常用编码技术的快速指南。" target="_self"><span>速查表</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/styleguide" title="写出 Angular 风格的程序" target="_self"><span>风格指南</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/glossary" title="Angular 中最重要的词汇的简要定义。" target="_self"><span>词汇表</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button type="button" class="vertical-menu-item heading level-1 collapsed ng-star-inserted" title="Angular CLI 命令参考手册。" aria-pressed="false"><span>CLI 命令</span><mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli" title="CLI 工具介绍、命令、语法" target="_self"><span>概览</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/usage-analytics-gathering" title="管理员如何从用户那里收集使用情况分析。" target="_self"><span>使用情况分析</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/add" title="ng add." target="_self"><span>ng add</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/analytics" title="ng analytics." target="_self"><span>ng analytics</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/build" title="ng build." target="_self"><span>ng build</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/config" title="ng config." target="_self"><span>ng config</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/deploy" title="ng deploy." target="_self"><span>ng deploy</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/doc" title="ng doc." target="_self"><span>ng doc</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/e2e" title="ng e2e." target="_self"><span>ng e2e</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/generate" title="ng generate." target="_self"><span>ng generate</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/help" title="ng help." target="_self"><span>ng help</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/lint" title="ng lint." target="_self"><span>ng lint</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/new" title="ng new." target="_self"><span>ng new</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/run" title="ng run." target="_self"><span>ng run</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/serve" title="ng serve." target="_self"><span>ng serve</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/test" title="ng test." target="_self"><span>ng test</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/update" title="ng update." target="_self"><span>ng update</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/version" title="ng version." target="_self"><span>ng version</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/xi18n" title="ng xi18n." target="_self"><span>ng xi18n</span></a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="api" title="关于 Angular 中类和值的详细信息。" target="_self"><span>API 参考手册</span></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><div class="mat-divider ng-star-inserted" style="margin:4px 20px;border-top:1px solid #d3d3d3"></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://github.com/ng-docs/ng-docs.github.io/issues" title="github 上的中文互助问答区" target="_blank"><span>互助问答</span><mat-icon role="img" class="mat-icon notranslate material-icons mat-icon-no-color ng-star-inserted" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://material.angular.cn" title="Angular Material 组件库的中文文档" target="_blank"><span>官方 Material 组件库</span><mat-icon role="img" class="mat-icon notranslate material-icons mat-icon-no-color ng-star-inserted" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng.ant.design/" title="Ant Design 的 Angular 实现，服务于企业级后台产品。" target="_blank"><span>ng-zorro 组件库</span><mat-icon role="img" class="mat-icon notranslate material-icons mat-icon-no-color ng-star-inserted" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://devui.design/" title="“华为云” 开源的企业级组件库，核心设计思想是：致简、沉浸、灵活" target="_blank"><span>华为 DevUI 组件库</span><mat-icon role="img" class="mat-icon notranslate material-icons mat-icon-no-color ng-star-inserted" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng.mobile.ant.design/" title="Ant Design Mobile 的 Angular 实现，服务于无线产品。" target="_blank"><span>ng-zorro mobile 组件库</span><mat-icon role="img" class="mat-icon notranslate material-icons mat-icon-no-color ng-star-inserted" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://flutter.cn/" title="Flutter 中文文档站" target="_blank"><span>友站：Flutter 中文</span><mat-icon role="img" class="mat-icon notranslate material-icons mat-icon-no-color ng-star-inserted" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item></aio-nav-menu><div class="doc-version ng-tns-c18-1"><aio-select><div class="form-select-menu"><button class="form-select-button"><span><strong></strong></span><span>stable (v9.0.0)</span></button></div></aio-select></div></div></mat-sidenav><div class="cdk-visually-hidden cdk-focus-trap-anchor" aria-hidden="true"></div><mat-sidenav-content cdkscrollable="" class="mat-drawer-content mat-sidenav-content ng-star-inserted" style="margin-left:261px"><main role="main" class="sidenav-content" id="guide-hierarchical-dependency-injection"><aio-mode-banner></aio-mode-banner><aio-doc-viewer class=""><div style="opacity:1"><div class="github-links"><a href="https://github.com/angular/angular-cn/edit/aio/aio/content/guide/hierarchical-dependency-injection.md?message=docs%3A%20请简述你的修改..." aria-label="提供编辑建议" title="提供编辑建议"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a></div><div class="content"><h1 id="hierarchical-injectors" translation-result="on">多级注入器<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#hierarchical-injectors"><i class="material-icons">link</i></a></h1><aio-toc class="embedded" ng-version="9.0.0-rc.11"><div class="toc-inner no-print collapsed ng-star-inserted"><button type="button" title="Expand/collapse contents" aria-label="Expand/collapse contents" class="toc-heading embedded secondary ng-star-inserted" aria-pressed="false">目录<mat-icon role="img" svgicon="keyboard_arrow_right" class="mat-icon notranslate rotating-icon collapsed mat-icon-no-color" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><ul class="toc-list embedded"><li class="h2 ng-star-inserted" title="两个注入器层次结构"><a href="guide/hierarchical-dependency-injection#two-injector-hierarchies">两个注入器层次结构</a></li><li class="h3 ng-star-inserted" title="ModuleInjector"><a href="guide/hierarchical-dependency-injection#moduleinjector"><code>ModuleInjector</code></a></li><li class="h3 ng-star-inserted" title="ElementInjector"><a href="guide/hierarchical-dependency-injection#elementinjector"><code>ElementInjector</code></a></li><li class="h2 secondary ng-star-inserted" title="解析规则"><a href="guide/hierarchical-dependency-injection#resolution-rules">解析规则</a></li><li class="h2 secondary ng-star-inserted" title="解析修饰符"><a href="guide/hierarchical-dependency-injection#resolution-modifiers">解析修饰符</a></li><li class="h3 secondary ng-star-inserted" title="修饰符的类型"><a href="guide/hierarchical-dependency-injection#types-of-modifiers">修饰符的类型</a></li><li class="h3 secondary ng-star-inserted" title="@Optional()"><a href="guide/hierarchical-dependency-injection#optional"><code>@Optional()</code></a></li><li class="h3 secondary ng-star-inserted" title="@Self()"><a href="guide/hierarchical-dependency-injection#self"><code>@Self()</code></a></li><li class="h3 secondary ng-star-inserted" title="@SkipSelf()"><a href="guide/hierarchical-dependency-injection#skipself"><code>@SkipSelf()</code></a></li><li class="h3 secondary ng-star-inserted" title="@Host()"><a href="guide/hierarchical-dependency-injection#host"><code>@Host()</code></a></li><li class="h2 secondary ng-star-inserted" title="模板的逻辑结构"><a href="guide/hierarchical-dependency-injection#logical-structure-of-the-template">模板的逻辑结构</a></li><li class="h2 secondary ng-star-inserted" title="在 @Component() 中提供服务"><a href="guide/hierarchical-dependency-injection#providing-services-in-component">在 <code>@Component()</code> 中提供服务</a></li><li class="h3 secondary ng-star-inserted" title="应用程序结构示例"><a href="guide/hierarchical-dependency-injection#example-app-structure">应用程序结构示例</a></li><li class="h3 secondary ng-star-inserted" title="使用 providers 数组"><a href="guide/hierarchical-dependency-injection#using-the-providers-array">使用 <code>providers</code> 数组</a></li><li class="h3 secondary ng-star-inserted" title="使用 viewProviders 数组"><a href="guide/hierarchical-dependency-injection#using-the-viewproviders-array">使用 <code>viewProviders</code> 数组</a></li><li class="h3 secondary ng-star-inserted" title="providers 与 viewProviders"><a href="guide/hierarchical-dependency-injection#providers-vs-viewproviders"><code>providers</code> 与 <code>viewProviders</code></a></li><li class="h2 secondary ng-star-inserted" title="修改服务可见性"><a href="guide/hierarchical-dependency-injection#modifying-service-visibility">修改服务可见性</a></li><li class="h3 secondary ng-star-inserted" title="提供者令牌的可见性"><a href="guide/hierarchical-dependency-injection#visibility-of-provided-tokens">提供者令牌的可见性</a></li><li class="h3 secondary ng-star-inserted" title="@SkipSelf() 和 viewProviders"><a href="guide/hierarchical-dependency-injection#skipself-and-viewproviders"><code>@SkipSelf()</code> 和 <code>viewProviders</code></a></li><li class="h3 secondary ng-star-inserted" title="@Host() 和 viewProviders"><a href="guide/hierarchical-dependency-injection#host-and-viewproviders"><code>@Host()</code> 和 <code>viewProviders</code></a></li><li class="h2 secondary ng-star-inserted" title="ElementInjector 用例示例"><a href="guide/hierarchical-dependency-injection#elementinjector-use-case-examples"><code>ElementInjector</code> 用例示例</a></li><li class="h3 secondary ng-star-inserted" title="场景：服务隔离"><a href="guide/hierarchical-dependency-injection#scenario-service-isolation">场景：服务隔离</a></li><li class="h3 secondary ng-star-inserted" title="场景：多重编辑会话"><a href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions">场景：多重编辑会话</a></li><li class="h3 secondary ng-star-inserted" title="场景：专门的提供者"><a href="guide/hierarchical-dependency-injection#scenario-specialized-providers">场景：专门的提供者</a></li><li class="h2 secondary ng-star-inserted" title="关于依赖注入的更多知识"><a href="guide/hierarchical-dependency-injection#more-on-dependency-injection">关于依赖注入的更多知识</a></li></ul><button type="button" title="Expand/collapse contents" aria-label="Expand/collapse contents" class="toc-more-items embedded material-icons collapsed ng-star-inserted" aria-pressed="false"></button></div></aio-toc><h1 translation-origin="off" id="hierarchical-injectors">Hierarchical injectors<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#hierarchical-injectors"><i class="material-icons">link</i></a></h1><p translation-result="on">Angular 中的注入器有一些规则，您可以利用这些规则来在应用程序中获得所需的可注入对象可见性。通过了解这些规则，可以确定应在哪个 NgModule、组件或指令中声明服务提供者。</p><p translation-origin="off">Injectors in Angular have rules that you can leverage to achieve the desired visibility of injectables in your apps. By understanding these rules, you can determine in which NgModule, Component or Directive you should declare a provider.</p><h2 id="two-injector-hierarchies" translation-result="on">两个注入器层次结构<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#two-injector-hierarchies"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="two-injector-hierarchies">Two injector hierarchies<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#two-injector-hierarchies"><i class="material-icons">link</i></a></h2><p translation-result="on">Angular 中有两个注入器层次结构：</p><p translation-origin="off">There are two injector hierarchies in Angular:</p><ol><li><p translation-result="on"> <code>ModuleInjector</code> 层次结构 —— 使用 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 或 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 注解在此层次结构中配置 <code>ModuleInjector</code>。</p><p translation-origin="off"><code>ModuleInjector</code> hierarchy—configure a <code>ModuleInjector</code> in this hierarchy using an <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> or <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> annotation.</p></li></ol><ol><li><p translation-result="on"> <code>ElementInjector</code> 层次结构 —— 在每个 DOM 元素上隐式创建。除非您在 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> 或 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 的 <code>providers</code> 属性中进行配置，否则默认情况下，<code>ElementInjector</code> 为空。</p><p translation-origin="off"><code>ElementInjector</code> hierarchy—created implicitly at each DOM element. An <code>ElementInjector</code> is empty by default unless you configure it in the <code>providers</code> property on <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> or <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code>.</p></li></ol><a id="register-providers-injectable"></a><h3 id="moduleinjector"><code>ModuleInjector</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#moduleinjector"><i class="material-icons">link</i></a></h3><p translation-result="on">可以通过以下两种方式之一配置 <code>ModuleInjector</code> ：</p><p translation-origin="off">The <code>ModuleInjector</code> can be configured in one of two ways:</p><ul><li><p translation-result="on">使用 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 的 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 属性引用 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 或 <code>root</code> 。</p><p translation-origin="off">Using the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> property to refer to <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code>, or <code>root</code>.</p></li><li><p translation-result="on">使用 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 的 <code>providers</code> 数组。</p><p translation-origin="off">Using the <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> <code>providers</code> array.</p></li></ul><div class="is-helpful alert"><h4 id="tree-shaking-and-injectable" translation-result="on">摇树优化与 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#tree-shaking-and-injectable"><i class="material-icons">link</i></a></h4><h4 translation-origin="off" id="tree-shaking-and-injectable">Tree-shaking and <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#tree-shaking-and-injectable"><i class="material-icons">link</i></a></h4><p translation-result="on">使用 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 的 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 属性优于 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 的 <code>providers</code> 数组，因为使用 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 的 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 时，优化工具可以进行摇树优化，从而删除您的应用程序中未使用的服务，以减小捆绑包尺寸。</p><p translation-origin="off">Using the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> property is preferable to the <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> <code>providers</code> array because with <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code>, optimization tools can perform tree-shaking, which removes services that your app isn't using and results in smaller bundle sizes.</p><p translation-result="on">摇树优化对于库特别有用，因为使用该库的应用程序不需要注入它。在 <a href="guide/dependency-injection-providers">DI 提供者中</a>了解有关<a href="guide/dependency-injection-providers#tree-shakable-providers">可摇树优化的提供者</a>的更多信息。</p><p translation-origin="off">Tree-shaking is especially useful for a library because the application which uses the library may not have a need to inject it. Read more about <a href="guide/dependency-injection-providers#tree-shakable-providers">tree-shakable providers</a> in <a href="guide/dependency-injection-providers">DI Providers</a>.</p></div><p translation-result="on"><code>ModuleInjector</code> 由 <code>@<a href="api/core/NgModule#providers" class="code-anchor">NgModule.providers</a></code> 和 <code><a href="api/core/NgModule#imports" class="code-anchor">NgModule.imports</a></code> 属性配置。 <code>ModuleInjector</code> 是可以通过 <code><a href="api/core/NgModule#imports" class="code-anchor">NgModule.imports</a></code> 递归找到的所有 providers 数组的扁平化。</p><p translation-origin="off"><code>ModuleInjector</code> is configured by the <code>@<a href="api/core/NgModule#providers" class="code-anchor">NgModule.providers</a></code> and <code><a href="api/core/NgModule#imports" class="code-anchor">NgModule.imports</a></code> property. <code>ModuleInjector</code> is a flattening of all of the providers arrays which can be reached by following the <code><a href="api/core/NgModule#imports" class="code-anchor">NgModule.imports</a></code> recursively.</p><p translation-result="on">子 <code>ModuleInjector</code> 是在延迟加载其它 <code>@NgModules</code> 时创建的。</p><p translation-origin="off">Child <code>ModuleInjector</code>s are created when lazy loading other <code>@NgModules</code>.</p><p translation-result="on">使用 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 的 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 属性提供服务的方式如下：</p><p translation-origin="off">Provide services with the <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> property of <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> as follows:</p><code-example language="ts" ng-version="9.0.0-rc.11"><div style="display:none">import { <a href="api/core/Injectable" class="code-anchor">Injectable</a> } from '@angular/core'; @<a href="api/core/Injectable" class="code-anchor">Injectable</a>({ <a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>: 'root' // &lt;--provides this service in the root ModuleInjector }) export class ItemService { name = 'telephone'; }</div><aio-code><pre class="lang-ts prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Injectable" class="code-anchor"><span class="typ">Injectable</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> from </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Injectable" class="code-anchor"><span class="lit">Injectable</span></a><span class="pun">({</span><span class="pln">
  </span><a href="api/core/Injectable#providedIn" class="code-anchor"><span class="pln">providedIn</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'root'</span><span class="pln">  </span><span class="com">// &lt;--provides this service in the root ModuleInjector</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ItemService</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'telephone'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 装饰器标识服务类。该 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 属性配置指定的 <code>ModuleInjector</code>，这里的 <code>root</code> 会把让该服务在 <code>root</code> <code>ModuleInjector</code> 上可用。</p><p translation-origin="off">The <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> decorator identifies a service class. The <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> property configures a specific <code>ModuleInjector</code>, here <code>root</code>, which makes the service available in the <code>root</code> <code>ModuleInjector</code>.</p><h4 id="platform-injector" translation-result="on">平台注入器<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#platform-injector"><i class="material-icons">link</i></a></h4><h4 translation-origin="off" id="platform-injector">Platform injector<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#platform-injector"><i class="material-icons">link</i></a></h4><p translation-result="on">在 <code>root</code> 之上还有两个注入器，一个是额外的 <code>ModuleInjector</code>，一个是 <code>NullInjector()</code>。</p><p translation-origin="off">There are two more injectors above <code>root</code>, an additional <code>ModuleInjector</code> and <code>NullInjector()</code>.</p><p translation-result="on">思考下 Angular 要如何通过 <code>main.ts</code> 中的如下代码引导应用程序：</p><p translation-origin="off">Consider how Angular bootstraps the app with the following in <code>main.ts</code>:</p><code-example language="javascript" ng-version="9.0.0-rc.11"><div style="display:none"><a href="api/platform-browser-dynamic/platformBrowserDynamic" class="code-anchor">platformBrowserDynamic</a>().bootstrapModule(AppModule).then(ref =&gt; {...})</div><aio-code><pre class="lang-javascript prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><a href="api/platform-browser-dynamic/platformBrowserDynamic" class="code-anchor"><span class="pln">platformBrowserDynamic</span></a><span class="pun">().</span><span class="pln">bootstrapModule</span><span class="pun">(</span><span class="typ">AppModule</span><span class="pun">).</span><span class="pln">then</span><span class="pun">(</span><span class="pln">ref </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">{...})</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code><a href="api/core/PlatformRef#bootstrapModule" class="code-anchor">bootstrapModule()</a></code> 方法会创建一个由 <code>AppModule</code> 配置的注入器作为平台注入器的子注入器。也就是 <code>root</code> <code>ModuleInjector</code>。</p><p translation-origin="off">The <code><a href="api/core/PlatformRef#bootstrapModule" class="code-anchor">bootstrapModule()</a></code> method creates a child injector of the platform injector which is configured by the <code>AppModule</code>. This is the <code>root</code> <code>ModuleInjector</code>.</p><p translation-result="on"><code><a href="api/platform-browser-dynamic/platformBrowserDynamic" class="code-anchor">platformBrowserDynamic</a>()</code> 方法创建一个由 <code>PlatformModule</code> 配置的注入器，该注入器包含特定平台的依赖项。这允许多个应用共享同一套平台配置。例如，无论您运行多少个应用程序，浏览器都只有一个 URL 栏。您可以使用 <code><a href="api/platform-browser/platformBrowser" class="code-anchor">platformBrowser</a>()</code> 函数提供 <code>extraProviders</code>，从而在平台级别配置特定平台的额外提供者。</p><p translation-origin="off">The <code><a href="api/platform-browser-dynamic/platformBrowserDynamic" class="code-anchor">platformBrowserDynamic</a>()</code> method creates an injector configured by a <code>PlatformModule</code>, which contains platform-specific dependencies. This allows multiple apps to share a platform configuration. For example, a browser has only one URL bar, no matter how many apps you have running. You can configure additional platform-specific providers at the platform level by supplying <code>extraProviders</code> using the <code><a href="api/platform-browser/platformBrowser" class="code-anchor">platformBrowser</a>()</code> function.</p><p translation-result="on">层次结构中的下一个父注入器是 <code>NullInjector()</code>，它是树的顶部。如果您在树中向上走了很远，以至于要在 <code>NullInjector()</code> 中寻找服务，那么除非使用 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code>，否则将收到错误消息，因为最终所有东西都将以 <code>NullInjector()</code> 结束并返回错误，或者对于 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code>，返回 <code>null</code>。有关 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> 的更多信息，请参见本指南的 <a href="guide/hierarchical-dependency-injection#optional"><code>@Optional()</code> 部分</a> 。</p><p translation-origin="off">The next parent injector in the hierarchy is the <code>NullInjector()</code>, which is the top of the tree. If you've gone so far up the tree that you are looking for a service in the <code>NullInjector()</code>, you'll get an error unless you've used <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> because ultimately, everything ends at the <code>NullInjector()</code> and it returns an error or, in the case of <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code>, <code>null</code>. For more information on <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code>, see the <a href="guide/hierarchical-dependency-injection#optional"><code>@Optional()</code> section</a> of this guide.</p><p translation-result="on">下图展示了前面各段落描述的 <code>root</code> <code>ModuleInjector</code> 及其父注入器之间的关系。</p><p translation-origin="off">The following diagram represents the relationship between the <code>root</code> <code>ModuleInjector</code> and its parent injectors as the previous paragraphs describe.</p><div class="lightbox"><img src="generated/images/guide/dependency-injection/injectors.svg" alt="NullInjector, ModuleInjector, root injector" width="600" height="445"></div><p translation-result="on">虽然 <code>root</code> 是一个特殊的别名，但其他 <code>ModuleInjector</code> 都没有别名。每当创建动态加载组件时，你还会创建 <code>ModuleInjector</code>，比如路由器，它还会创建子 <code>ModuleInjector</code>。</p><p translation-origin="off">While the name <code>root</code> is a special alias, other <code>ModuleInjector</code>s don't have aliases. You have the option to create <code>ModuleInjector</code>s whenever a dynamically loaded component is created, such as with the Router, which will create child <code>ModuleInjector</code>s.</p><p translation-result="on">无论是使用 <code><a href="api/core/PlatformRef#bootstrapModule" class="code-anchor">bootstrapModule()</a></code> 的方法配置它，还是将所有提供者都用 <code>root</code> 注册到其自己的服务中，所有请求最终都会转发到 <code>root</code> 注入器。</p><p translation-origin="off">All requests forward up to the root injector, whether you configured it with the <code><a href="api/core/PlatformRef#bootstrapModule" class="code-anchor">bootstrapModule()</a></code> method, or registered all providers with <code>root</code> in their own services.</p><div class="alert is-helpful"><h4 id="injectable-vs-ngmodule"><code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> vs. <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#injectable-vs-ngmodule"><i class="material-icons">link</i></a></h4><p translation-result="on">如果你在 <code>AppModule</code> 的 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 中配置应用级提供者，它就会覆盖一个在 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 的 <code>root</code> 元数据中配置的提供者。您可以用这种方式，来配置供多个应用共享的服务的非默认提供者。</p><p translation-origin="off">If you configure an app-wide provider in the <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> of <code>AppModule</code>, it overrides one configured for <code>root</code> in the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> metadata. You can do this to configure a non-default provider of a service that is shared with multiple apps.</p><p translation-result="on">下面的例子中，通过把 <a href="guide/router#location-strategy">location 策略</a> 的提供者添加到 <code>AppModule</code> 的 <code>providers</code> 列表中，为路由器配置了非默认的 <a href="guide/router#location-strategy">location 策略</a>。</p><p translation-origin="off">Here is an example of the case where the component router configuration includes a non-default <a href="guide/router#location-strategy">location strategy</a> by listing its provider in the <code>providers</code> list of the <code>AppModule</code>.</p><code-example path="dependency-injection-in-action/src/app/app.module.ts" region="providers" header="src/app/app.module.ts (providers)" ng-version="9.0.0-rc.11"><div style="display:none">providers: [ { provide: <a href="api/common/LocationStrategy" class="code-anchor">LocationStrategy</a>, useClass: <a href="api/common/HashLocationStrategy" class="code-anchor">HashLocationStrategy</a> } ]</div><header class="ng-star-inserted">src/app/app.module.ts (providers)</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from src/app/app.module.ts (providers)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="pln">providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
  </span><span class="pun">{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><a href="api/common/LocationStrategy" class="code-anchor"><span class="typ">LocationStrategy</span></a><span class="pun">,</span><span class="pln"> useClass</span><span class="pun">:</span><span class="pln"> </span><a href="api/common/HashLocationStrategy" class="code-anchor"><span class="typ">HashLocationStrategy</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">]</span></code>
    </pre></aio-code></code-example></div><h3 id="elementinjector"><code>ElementInjector</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#elementinjector"><i class="material-icons">link</i></a></h3><p translation-result="on">Angular 会为每个 DOM 元素隐式创建 <code>ElementInjector</code> 。</p><p translation-origin="off">Angular creates <code>ElementInjector</code>s implicitly for each DOM element.</p><p translation-result="on">可以用 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 装饰器中的 <code>providers</code> 或 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 属性来配置 <code>ElementInjector</code> 以提供服务。例如，下面的 <code>TestComponent</code> 通过提供此服务来配置 <code>ElementInjector</code>：</p><p translation-origin="off">Providing a service in the <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> decorator using its <code>providers</code> or <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> property configures an <code>ElementInjector</code>. For example, the following <code>TestComponent</code> configures the <code>ElementInjector</code> by providing the service as follows:</p><code-example language="ts" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ ... providers: [{ provide: ItemService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { name: 'lamp' } }] }) export class TestComponent</div><aio-code><pre class="lang-ts prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">ItemService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> </span><span class="str">'lamp'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">TestComponent</span></code>
    </pre></aio-code></code-example><div class="alert is-helpful"><p translation-result="on"><strong>注意：</strong>请参阅<a href="guide/hierarchical-dependency-injection#resolution-rules">解析规则</a>部分，以了解 <code>ModuleInjector</code> 树和 <code>ElementInjector</code> 树之间的关系。</p><p translation-origin="off"><strong>Note:</strong> Please see the <a href="guide/hierarchical-dependency-injection#resolution-rules">resolution rules</a> section to understand the relationship between the <code>ModuleInjector</code> tree and the <code>ElementInjector</code> tree.</p></div><p translation-result="on">在组件中提供服务时，可以通过 <code>ElementInjector</code> 在该组件实例处使用该服务。根据<a href="guide/hierarchical-dependency-injection#resolution-rules">解析规则</a>部分描述的可见性规则，它也同样在子组件/指令处可见。</p><p translation-origin="off">When you provide services in a component, that service is available via the <code>ElementInjector</code> at that component instance. It may also be visible at child component/directives based on visibility rules described in the <a href="guide/hierarchical-dependency-injection#resolution-rules">resolution rules</a> section.</p><p translation-result="on">当组件实例被销毁时，该服务实例也将被销毁。</p><p translation-origin="off">When the component instance is destroyed, so is that service instance.</p><h4 id="directive-and-component" translation-result="on"><code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> 和 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#directive-and-component"><i class="material-icons">link</i></a></h4><h4 translation-origin="off" id="directive-and-component"><code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> and <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#directive-and-component"><i class="material-icons">link</i></a></h4><p translation-result="on">组件是一种特殊类型的指令，这意味着 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> 具有 <code>providers</code> 属性，<code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 也同样如此。 这意味着指令和组件都可以使用 <code>providers</code> 属性来配置提供者。当使用 <code>providers</code> 属性为组件或指令配置提供者时，该提供程商就属于该组件或指令的 <code>ElementInjector</code>。同一元素上的组件和指令共享同一个注入器。</p><p translation-origin="off">A component is a special type of directive, which means that just as <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> has a <code>providers</code> property, <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> does too. This means that directives as well as components can configure providers, using the <code>providers</code> property. When you configure a provider for a component or directive using the <code>providers</code> property, that provider belongs to the <code>ElementInjector</code> of that component or directive. Components and directives on the same element share an injector.</p><a id="resolution-rules"></a><h2 id="resolution-rules" translation-result="on">解析规则<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#resolution-rules"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="resolution-rules">Resolution rules<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#resolution-rules"><i class="material-icons">link</i></a></h2><p translation-result="on">当为组件/指令解析令牌时，Angular 分为两个阶段来解析它：</p><p translation-origin="off">When resolving a token for a component/directive, Angular resolves it in two phases:</p><ol><li><p translation-result="on">针对 <code>ElementInjector</code> 层次结构（其父级）</p><p translation-origin="off">Against the <code>ElementInjector</code> hierarchy (its parents)</p></li></ol><ol><li><p translation-result="on">针对 <code>ModuleInjector</code> 层次结构（其父级）</p><p translation-origin="off">Against the <code>ModuleInjector</code> hierarchy (its parents)</p></li></ol><p translation-result="on">当组件声明依赖项时，Angular 会尝试使用它自己的 <code>ElementInjector</code> 来满足该依赖。 如果组件的注入器缺少提供者，它将把请求传给其父组件的 <code>ElementInjector</code> 。</p><p translation-origin="off">When a component declares a dependency, Angular tries to satisfy that dependency with its own <code>ElementInjector</code>. If the component's injector lacks the provider, it passes the request up to its parent component's <code>ElementInjector</code>.</p><p translation-result="on">这些请求将继续转发，直到 Angular 找到可以处理该请求的注入器或用完祖先 <code>ElementInjector</code> 。</p><p translation-origin="off">The requests keep forwarding up until Angular finds an injector that can handle the request or runs out of ancestor <code>ElementInjector</code>s.</p><p translation-result="on">如果 Angular 在任何 <code>ElementInjector</code> 中都找不到提供者，它将返回到发起请求的元素，并在 <code>ModuleInjector</code> 层次结构中进行查找。如果 Angular 仍然找不到提供者，它将引发错误。</p><p translation-origin="off">If Angular doesn't find the provider in any <code>ElementInjector</code>s, it goes back to the element where the request originated and looks in the <code>ModuleInjector</code> hierarchy. If Angular still doesn't find the provider, it throws an error.</p><p translation-result="on">如果您已在不同级别注册了相同 DI 令牌的提供者，则 Angular 会用遇到的第一个来解析该依赖。例如，如果提供者已经在需要此服务的组件中本地注册了，则 Angular 不会再寻找同一服务的其他提供者。</p><p translation-origin="off">If you have registered a provider for the same DI token at different levels, the first one Angular encounters is the one it uses to resolve the dependency. If, for example, a provider is registered locally in the component that needs a service, Angular doesn't look for another provider of the same service.</p><h2 id="resolution-modifiers" translation-result="on">解析修饰符<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#resolution-modifiers"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="resolution-modifiers">Resolution modifiers<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#resolution-modifiers"><i class="material-icons">link</i></a></h2><p translation-result="on">可以使用 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code>，<code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code>，<code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 和 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 来修饰 Angular 的解析行为。从 <code>@angular/core</code> 导入它们，并在注入服务时在组件类构造函数中使用它们。</p><p translation-origin="off">Angular's resolution behavior can be modified with <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code>, <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code>, <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> and <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code>. Import each of them from <code>@angular/core</code> and use each in the component class constructor when you inject your service.</p><p translation-result="on">有关展示本节介绍的解析修饰符的可运行应用，请参阅<live-example name="resolution-modifiers" ng-version="9.0.0-rc.11"><span style="display:none">解析修饰符范例</span><span><span class="ng-star-inserted"><a target="_blank" title="解析修饰符范例" href="generated/live-examples/resolution-modifiers/stackblitz.html">解析修饰符范例</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/resolution-modifiers/resolution-modifiers.zip">下载范例</a></span></span></span></live-example>。</p><p translation-origin="off">For a working app showcasing the resolution modifiers that this section covers, see the<live-example name="resolution-modifiers" ng-version="9.0.0-rc.11"><span style="display:none">resolution modifiers example</span><span><span class="ng-star-inserted"><a target="_blank" title="resolution modifiers example" href="generated/live-examples/resolution-modifiers/stackblitz.html">resolution modifiers example</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/resolution-modifiers/resolution-modifiers.zip">下载范例</a></span></span></span></live-example>.</p><h3 id="types-of-modifiers" translation-result="on">修饰符的类型<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#types-of-modifiers"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="types-of-modifiers">Types of modifiers<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#types-of-modifiers"><i class="material-icons">link</i></a></h3><p translation-result="on">解析修饰符分为三类：</p><p translation-origin="off">Resolution modifiers fall into three categories:</p><ol><li><p translation-result="on">如果 Angular 找不到您要的东西该怎么办，用 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code></p><p translation-origin="off">What to do if Angular doesn't find what you're looking for, that is <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code></p></li></ol><ol start="2"><li><p translation-result="on">从哪里开始寻找，用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code></p><p translation-origin="off">Where to start looking, that is <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code></p></li></ol><ol start="3"><li><p translation-result="on">到哪里停止寻找，用 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 和 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code></p><p translation-origin="off">Where to stop looking, <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> and <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code></p></li></ol><p translation-result="on">默认情况下，Angular 始终从当前的 <code><a href="api/core/Injector" class="code-anchor">Injector</a></code> 开始，并一直向上搜索。修饰符使您可以更改开始（默认是自己）或结束位置。</p><p translation-origin="off">By default, Angular always starts at the current <code><a href="api/core/Injector" class="code-anchor">Injector</a></code> and keeps searching all the way up. Modifiers allow you to change the starting (self) or ending location.</p><p translation-result="on">另外，您可以组合除 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 和 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 之外的所有修饰符，当然还有 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 和 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 。</p><p translation-origin="off">Additionally, you can combine all of the modifiers except <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> and <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> and of course <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> and <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code>.</p><a id="optional"></a><h3 id="optional"><code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#optional"><i class="material-icons">link</i></a></h3><p translation-result="on"><code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> 允许 Angular 将您注入的服务视为可选服务。这样，如果无法在运行时解析它，Angular 只会将服务解析为 <code>null</code>，而不会抛出错误。在下面的示例中，服务 <code>OptionalService</code> 没有在 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 或组件类中提供，所以它没有在应用中的任何地方。</p><p translation-origin="off"><code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> allows Angular to consider a service you inject to be optional. This way, if it can't be resolved at runtime, Angular simply resolves the service as <code>null</code>, rather than throwing an error. In the following example, the service, <code>OptionalService</code>, isn't provided in the service, <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code>, or component class, so it isn't available anywhere in the app.</p><code-example path="resolution-modifiers/src/app/optional/optional.component.ts" header="resolution-modifiers/src/app/optional/optional.component.ts" region="optional-component" ng-version="9.0.0-rc.11"><div style="display:none">export class OptionalComponent { constructor(@<a href="api/core/Optional" class="code-anchor">Optional</a>() public <a href="api/animations/AnimationQueryOptions#optional" class="code-anchor">optional</a>: OptionalService) {} }</div><header class="ng-star-inserted">resolution-modifiers/src/app/optional/optional.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from resolution-modifiers/src/app/optional/optional.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">OptionalComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/Optional" class="code-anchor"><span class="lit">Optional</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> </span><a href="api/animations/AnimationQueryOptions#optional" class="code-anchor"><span class="pln">optional</span></a><span class="pun">:</span><span class="pln"> </span><span class="typ">OptionalService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><h3 id="self"><code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#self"><i class="material-icons">link</i></a></h3><p translation-result="on">使用 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 让 Angular 仅查看当前组件或指令的 <code>ElementInjector</code> 。</p><p translation-origin="off">Use <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> so that Angular will only look at the <code>ElementInjector</code> for the current component or directive.</p><p translation-result="on"><code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 的一个好例子是要注入某个服务，但只有当该服务在当前宿主元素上可用时才行。为了避免这种情况下出错，请将 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 与 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> 结合使用。</p><p translation-origin="off">A good use case for <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> is to inject a service but only if it is available on the current host element. To avoid errors in this situation, combine <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> with <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code>.</p><p translation-result="on">例如，在下面的 <code>SelfComponent</code> 中。请注意在构造函数中注入的 <code>LeafService</code>。</p><p translation-origin="off">For example, in the following <code>SelfComponent</code>, notice the injected <code>LeafService</code> in the constructor.</p><code-example path="resolution-modifiers/src/app/self-no-data/self-no-data.component.ts" header="resolution-modifiers/src/app/self-no-data/self-no-data.component.ts" region="self-no-data-component" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-self-no-data', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './self-no-data.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: ['./self-no-data.component.css'] }) export class SelfNoDataComponent { constructor(@<a href="api/core/Self" class="code-anchor">Self</a>() @<a href="api/core/Optional" class="code-anchor">Optional</a>() public leaf: LeafService) { } }</div><header class="ng-star-inserted">resolution-modifiers/src/app/self-no-data/self-no-data.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from resolution-modifiers/src/app/self-no-data/self-no-data.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-self-no-data'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./self-no-data.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">'./self-no-data.component.css'</span><span class="pun">]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">SelfNoDataComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/Self" class="code-anchor"><span class="lit">Self</span></a><span class="pun">()</span><span class="pln"> </span><span class="lit">@</span><a href="api/core/Optional" class="code-anchor"><span class="lit">Optional</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> leaf</span><span class="pun">:</span><span class="pln"> </span><span class="typ">LeafService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">在这个例子中，有一个父提供者，注入服务将返回该值，但是，使用 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 和 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> 注入的服务将返回 <code>null</code> 因为 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 告诉注入器在当前宿主元素上就要停止搜索。</p><p translation-origin="off">In this example, there is a parent provider and injecting the service will return the value, however, injecting the service with <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> and <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> will return <code>null</code> because <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> tells the injector to stop searching in the current host element.</p><p translation-result="on">另一个示例显示了具有 <code>FlowerService</code> 提供者的组件类。在这个例子中，注入器没有超出当前 <code>ElementInjector</code> 就停止了，因为它已经找到了 <code>FlowerService</code> 并返回了黄色花朵🌼。</p><p translation-origin="off">Another example shows the component class with a provider for <code>FlowerService</code>. In this case, the injector looks no further than the current <code>ElementInjector</code> because it finds the <code>FlowerService</code> and returns the yellow flower 🌼.</p><code-example path="resolution-modifiers/src/app/self/self.component.ts" header="resolution-modifiers/src/app/self/self.component.ts" region="self-component" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-self', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './self.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: ['./self.component.css'], providers: [{ provide: FlowerService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🌼' } }] }) export class SelfComponent { constructor(@<a href="api/core/Self" class="code-anchor">Self</a>() public flower: FlowerService) {} }</div><header class="ng-star-inserted">resolution-modifiers/src/app/self/self.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from resolution-modifiers/src/app/self/self.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-self'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./self.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">'./self.component.css'</span><span class="pun">],</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🌼'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">

</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">SelfComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/Self" class="code-anchor"><span class="lit">Self</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> flower</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><h3 id="skipself"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#skipself"><i class="material-icons">link</i></a></h3><p translation-result="on"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 与 <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 相反。使用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> ，Angular 在父 <code>ElementInjector</code> 中而不是当前 <code>ElementInjector</code> 中开始搜索服务。因此，如果父 <code>ElementInjector</code> 对 <code>emoji</code> 使用了值 <code>🌿</code>（蕨类），但组件的 <code>providers</code> 数组中有 <code>🍁</code>（枫叶），则 Angular 将忽略 <code>🍁</code>（枫叶），而使用 <code>🌿</code>（蕨类）。</p><p translation-origin="off"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> is the opposite of <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code>. With <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>, Angular starts its search for a service in the parent <code>ElementInjector</code>, rather than in the current one. So if the parent <code>ElementInjector</code> were using the value <code>🌿</code> (fern) for <code>emoji</code> , but you had <code>🍁</code> (maple leaf) in the component's <code>providers</code> array, Angular would ignore <code>🍁</code> (maple leaf) and use <code>🌿</code> (fern).</p><p translation-result="on">要在代码中看到这一点，请先假定 <code>emoji</code> 的以下值就是父组件正在使用的值，如本服务所示：</p><p translation-origin="off">To see this in code, assume that the following value for <code>emoji</code> is what the parent component were using, as in this service:</p><code-example path="resolution-modifiers/src/app/leaf.service.ts" header="resolution-modifiers/src/app/leaf.service.ts" region="leafservice" ng-version="9.0.0-rc.11"><div style="display:none">export class LeafService { emoji = '🌿'; }</div><header class="ng-star-inserted">resolution-modifiers/src/app/leaf.service.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from resolution-modifiers/src/app/leaf.service.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">LeafService</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  emoji </span><span class="pun">=</span><span class="pln"> </span><span class="str">'🌿'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">想象一下，在子组件中，您有一个不同的值 <code>🍁</code>（枫叶），但您想使用父项的值。你就要使用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> ：</p><p translation-origin="off">Imagine that in the child component, you had a different value, <code>🍁</code> (maple leaf) but you wanted to use the parent's value instead. This is when you'd use <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>:</p><code-example path="resolution-modifiers/src/app/skipself/skipself.component.ts" header="resolution-modifiers/src/app/skipself/skipself.component.ts" region="skipself-component" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-skipself', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './skipself.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: ['./skipself.component.css'], // Angular would ignore this LeafService instance providers: [{ provide: LeafService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🍁' } }] }) export class SkipselfComponent { // Use @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() in the constructor constructor(@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() public leaf: LeafService) { } }</div><header class="ng-star-inserted">resolution-modifiers/src/app/skipself/skipself.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from resolution-modifiers/src/app/skipself/skipself.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-skipself'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./skipself.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">'./skipself.component.css'</span><span class="pun">],</span><span class="pln">
  </span><span class="com">// Angular would ignore this LeafService instance</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">LeafService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🍁'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">SkipselfComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// Use @</span><a href="api/core/SkipSelf" class="code-anchor"><span class="com">SkipSelf</span></a><span class="com">() in the constructor</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/SkipSelf" class="code-anchor"><span class="lit">SkipSelf</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> leaf</span><span class="pun">:</span><span class="pln"> </span><span class="typ">LeafService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">在这个例子中，您获得的 <code>emoji</code> 值将为 <code>🌿</code>（蕨类），而不是 <code>🍁</code>（枫叶）。</p><p translation-origin="off">In this case, the value you'd get for <code>emoji</code> would be <code>🌿</code> (fern), not <code>🍁</code> (maple leaf).</p><h4 id="skipself-with-optional"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> with <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#skipself-with-optional"><i class="material-icons">link</i></a></h4><p translation-result="on">如果值为 <code>null</code> 请同时使用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 和 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> 来防止错误。在下面的示例中，将 <code>Person</code> 服务注入到构造函数中。<code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 告诉 Angular 跳过当前的注入器，如果 <code>Person</code> 服务为 <code>null</code>，则 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> 将防止报错。</p><p translation-origin="off">Use <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> with <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> to prevent an error if the value is <code>null</code>. In the following example, the <code>Person</code> service is injected in the constructor. <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> tells Angular to skip the current injector and <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> will prevent an error should the <code>Person</code> service be <code>null</code>.</p><code-example language="ts" ng-version="9.0.0-rc.11"><div style="display:none">class Person { constructor(@<a href="api/core/Optional" class="code-anchor">Optional</a>() @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() parent: Person) {} }</div><aio-code><pre class="lang-ts prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Person</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/Optional" class="code-anchor"><span class="lit">Optional</span></a><span class="pun">()</span><span class="pln"> </span><span class="lit">@</span><a href="api/core/SkipSelf" class="code-anchor"><span class="lit">SkipSelf</span></a><span class="pun">()</span><span class="pln"> parent</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Person</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><h3 id="host"><code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#host"><i class="material-icons">link</i></a></h3><p translation-result="on"><code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 使您可以在搜索提供者时将当前组件指定为注入器树的最后一站。即使树的更上级有一个服务实例，Angular 也不会继续寻找。使用 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 的例子如下：</p><p translation-origin="off"><code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> lets you designate a component as the last stop in the injector tree when searching for providers. Even if there is a service instance further up the tree, Angular won't continue looking. Use <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> as follows:</p><code-example path="resolution-modifiers/src/app/host/host.component.ts" header="resolution-modifiers/src/app/host/host.component.ts" region="host-component" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-host', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './host.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: ['./host.component.css'], // provide the service providers: [{ provide: FlowerService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🌼' } }] }) export class HostComponent { // use @<a href="api/core/Host" class="code-anchor">Host</a>() in the constructor when injecting the service constructor(@<a href="api/core/Host" class="code-anchor">Host</a>() @<a href="api/core/Optional" class="code-anchor">Optional</a>() public flower: FlowerService) { } }</div><header class="ng-star-inserted">resolution-modifiers/src/app/host/host.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from resolution-modifiers/src/app/host/host.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-host'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./host.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">'./host.component.css'</span><span class="pun">],</span><span class="pln">
  </span><span class="com">//  provide the service</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🌼'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HostComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// use @</span><a href="api/core/Host" class="code-anchor"><span class="com">Host</span></a><span class="com">() in the constructor when injecting the service</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/Host" class="code-anchor"><span class="lit">Host</span></a><span class="pun">()</span><span class="pln"> </span><span class="lit">@</span><a href="api/core/Optional" class="code-anchor"><span class="lit">Optional</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> flower</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">由于 <code>HostComponent</code> 在其构造函数中具有 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> ，因此，无论 <code>HostComponent</code> 的父级是否可能有 <code>flower.emoji</code> 值，该 <code>HostComponent</code> 都将使用 <code>🌼</code>（黄色花朵）。</p><p translation-origin="off">Since <code>HostComponent</code> has <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> in its constructor, no matter what the parent of <code>HostComponent</code> might have as a <code>flower.emoji</code> value, the <code>HostComponent</code> will use <code>🌼</code> (yellow flower).</p><h2 id="logical-structure-of-the-template" translation-result="on">模板的逻辑结构<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#logical-structure-of-the-template"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="logical-structure-of-the-template">Logical structure of the template<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#logical-structure-of-the-template"><i class="material-icons">link</i></a></h2><p translation-result="on">在组件类中提供服务时，服务在 <code>ElementInjector</code> 树中的可见性是取决于您在何处以及如何提供这些服务。</p><p translation-origin="off">When you provide services in the component class, services are visible within the <code>ElementInjector</code> tree relative to where and how you provide those services.</p><p translation-result="on">了解 Angular 模板的基础逻辑结构将为您配置服务并进而控制其可见性奠定基础。</p><p translation-origin="off">Understanding the underlying logical structure of the Angular template will give you a foundation for configuring services and in turn control their visibility.</p><p translation-result="on">组件在模板中使用，如以下示例所示：</p><p translation-origin="off">Components are used in your templates, as in the following example:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root&gt; &lt;app-child&gt;&lt;/app-child&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root&gt;</span><span class="pln">
    </span><span class="tag">&lt;app-child&gt;&lt;/app-child&gt;</span><span class="pln">
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><div class="alert is-helpful"><p translation-result="on"><strong>注意：</strong>通常，您要在单独的文件中声明组件及其模板。为了理解注入系统的工作原理，从组合逻辑树的视角来看它们是很有帮助的。使用术语“逻辑”将其与渲染树（您的应用程序 DOM 树）区分开。为了标记组件模板的位置，本指南使用 <code>&lt;#VIEW&gt;</code> 伪元素，该元素实际上不存在于渲染树中，仅用于心智模型中。</p><p translation-origin="off"><strong>Note:</strong> Usually, you declare the components and their templates in separate files. For the purposes of understanding how the injection system works, it is useful to look at them from the point of view of a combined logical tree. The term logical distinguishes it from the render tree (your application DOM tree). To mark the locations of where the component templates are located, this guide uses the <code>&lt;#VIEW&gt;</code> pseudo element, which doesn't actually exist in the render tree and is present for mental model purposes only.</p></div><p translation-result="on">下面是如何将 <code>&lt;app-root&gt;</code> 和 <code>&lt;app-child&gt;</code> 视图树组合为单个逻辑树的示例：</p><p translation-origin="off">The following is an example of how the <code>&lt;app-root&gt;</code> and <code>&lt;app-child&gt;</code> view trees are combined into a single logical tree:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root&gt; &lt;#VIEW&gt; &lt;app-child&gt; &lt;#VIEW&gt; ...content goes here... &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root&gt;</span><span class="pln">
  &lt;#VIEW&gt;
    </span><span class="tag">&lt;app-child&gt;</span><span class="pln">
     &lt;#VIEW&gt;
       ...content goes here...
     &lt;/#VIEW&gt;
    </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">当您在组件类中配置服务时，了解这种 <code>&lt;#VIEW&gt;</code> 划界的思想尤其重要。</p><p translation-origin="off">Understanding the idea of the <code>&lt;#VIEW&gt;</code> demarcation is especially significant when you configure services in the component class.</p><h2 id="providing-services-in-component" translation-result="on">在 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 中提供服务<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#providing-services-in-component"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="providing-services-in-component">Providing services in <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#providing-services-in-component"><i class="material-icons">link</i></a></h2><p translation-result="on">您如何通过 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> （或 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> ）装饰器提供服务决定了它们的可见性。以下各节演示了 <code>providers</code> 和 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 以及使用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 和 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 修改服务可见性的方法。</p><p translation-origin="off">How you provide services via an <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> (or <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code>) decorator determines their visibility. The following sections demonstrate <code>providers</code> and <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> along with ways to modify service visibility with <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> and <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code>.</p><p translation-result="on">组件类可以通过两种方式提供服务：</p><p translation-origin="off">A component class can provide services in two ways:</p><ol><li><p translation-result="on">使用 <code>providers</code> 数组</p><p translation-origin="off">with a <code>providers</code> array</p></li></ol><code-example language="typescript=" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ ... providers: [ {provide: FlowerService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: {emoji: '🌺'}} ] })</div><aio-code><pre class="lang-typescript= prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🌺'</span><span class="pun">}}</span><span class="pln">
  </span><span class="pun">]</span><span class="pln">
</span><span class="pun">})</span></code>
    </pre></aio-code></code-example><ol start="2"><li><p translation-result="on">使用 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组</p><p translation-origin="off">with a <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array</p></li></ol><code-example language="typescript=" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ ... <a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a>: [ {provide: AnimalService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: {emoji: '🐶'}} ] })</div><aio-code><pre class="lang-typescript= prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
  </span><a href="api/core/Component#viewProviders" class="code-anchor"><span class="pln">viewProviders</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🐶'</span><span class="pun">}}</span><span class="pln">
  </span><span class="pun">]</span><span class="pln">
</span><span class="pun">})</span></code>
    </pre></aio-code></code-example><p translation-result="on">为了解 <code>providers</code> 和 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 对服务可见性的影响有何差异，以下各节将逐步构建一个<live-example name="providers-viewproviders" ng-version="9.0.0-rc.11"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" title="现场演练" href="generated/live-examples/providers-viewproviders/stackblitz.html">现场演练</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/providers-viewproviders/providers-viewproviders.zip">下载范例</a></span></span></span></live-example>并在代码和逻辑树中比较 <code>providers</code> 和 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 的作用。</p><p translation-origin="off">To understand how the <code>providers</code> and <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> influence service visibility differently, the following sections build a<live-example name="providers-viewproviders" ng-version="9.0.0-rc.11"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" title="现场演练" href="generated/live-examples/providers-viewproviders/stackblitz.html">现场演练</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/providers-viewproviders/providers-viewproviders.zip">下载范例</a></span></span></span></live-example>step-by-step and compare the use of <code>providers</code> and <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> in code and a logical tree.</p><div class="alert is-helpful"><p translation-result="on"><strong>注意：</strong>在逻辑树中，你会看到 <code>@Provide</code> ， <code>@<a href="api/core/Inject" class="code-anchor">Inject</a></code> 和 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a></code> ，这些不是真正的 HTML 属性，只是为了在这里证明其幕后的原理。</p><p translation-origin="off"><strong>NOTE:</strong> In the logical tree, you'll see <code>@Provide</code>, <code>@<a href="api/core/Inject" class="code-anchor">Inject</a></code>, and <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a></code>, which are not real HTML attributes but are here to demonstrate what is going on under the hood.</p><ul><li><p translation-result="on"> <code>@<a href="api/core/Inject" class="code-anchor">Inject</a>(Token)=&gt;Value</code> 表示，如果要将 <code>Token</code> 注入逻辑树中的此位置，则它的值为 <code><a href="" class="code-anchor">Value</a></code>。</p><p translation-origin="off"><code>@<a href="api/core/Inject" class="code-anchor">Inject</a>(Token)=&gt;Value</code> demonstrates that if <code>Token</code> is injected at this location in the logical tree its value would be <code><a href="" class="code-anchor">Value</a></code>.</p></li></ul><ul><li><p translation-result="on"> <code>@Provide(Token=Value)</code> 表示，在逻辑树中的此位置存在一个值为 <code><a href="" class="code-anchor">Value</a></code> 的 <code>Token</code> 提供者的声明。</p><p translation-origin="off"><code>@Provide(Token=Value)</code> demonstrates that there is a declaration of <code>Token</code> provider with value <code><a href="" class="code-anchor">Value</a></code> at this location in the logical tree.</p></li></ul><ul><li><p translation-result="on"> <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>(Token)</code> 表示，应在此位置使用后备的 <code><a href="api/core/NgModule" class="code-anchor">NgModule</a></code> 注入器。</p><p translation-origin="off"><code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>(Token)</code> demonstrates that a fallback <code><a href="api/core/NgModule" class="code-anchor">NgModule</a></code> injector should be used at this location.</p></li></ul></div><h3 id="example-app-structure" translation-result="on">应用程序结构示例<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#example-app-structure"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="example-app-structure">Example app structure<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#example-app-structure"><i class="material-icons">link</i></a></h3><p translation-result="on">示例应用程序的 <code>root</code> 提供了 <code>FlowerService</code>，其 <code>emoji</code> 值为 <code>🌺</code>（红色芙蓉）。</p><p translation-origin="off">The example app has a <code>FlowerService</code> provided in <code>root</code> with an <code>emoji</code> value of <code>🌺</code> (red hibiscus).</p><code-example path="providers-viewproviders/src/app/flower.service.ts" header="providers-viewproviders/src/app/flower.service.ts" region="flowerservice" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Injectable" class="code-anchor">Injectable</a>({ <a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>: 'root' }) export class FlowerService { emoji = '🌺'; }</div><header class="ng-star-inserted">providers-viewproviders/src/app/flower.service.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/flower.service.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Injectable" class="code-anchor"><span class="lit">Injectable</span></a><span class="pun">({</span><span class="pln">
  </span><a href="api/core/Injectable#providedIn" class="code-anchor"><span class="pln">providedIn</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'root'</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  emoji </span><span class="pun">=</span><span class="pln"> </span><span class="str">'🌺'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">考虑一个只有 <code>AppComponent</code> 和 <code>ChildComponent</code> 的简单应用程序。最基本的渲染视图看起来就像嵌套的 HTML 元素，例如：</p><p translation-origin="off">Consider a simple app with only an <code>AppComponent</code> and a <code>ChildComponent</code>. The most basic rendered view would look like nested HTML elements such as the following:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root&gt; &lt;!-- AppComponent selector --&gt; &lt;app-child&gt; &lt;!-- ChildComponent selector --&gt; &lt;/app-child&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root&gt;</span><span class="pln"> </span><span class="com">&lt;!-- AppComponent selector --&gt;</span><span class="pln">
    </span><span class="tag">&lt;app-child&gt;</span><span class="pln"> </span><span class="com">&lt;!-- ChildComponent selector --&gt;</span><span class="pln">
    </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">但是，在幕后，Angular 在解析注入请求时使用如下逻辑视图表示形式：</p><p translation-origin="off">However, behind the scenes, Angular uses a logical view representation as follows when resolving injection requests:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root&gt; &lt;!-- AppComponent selector --&gt; &lt;#VIEW&gt; &lt;app-child&gt; &lt;!-- ChildComponent selector --&gt; &lt;#VIEW&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root&gt;</span><span class="pln"> </span><span class="com">&lt;!-- AppComponent selector --&gt;</span><span class="pln">
    &lt;#VIEW&gt;
        </span><span class="tag">&lt;app-child&gt;</span><span class="pln"> </span><span class="com">&lt;!-- ChildComponent selector --&gt;</span><span class="pln">
            &lt;#VIEW&gt;
            &lt;/#VIEW&gt;
        </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
    &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">此处的 <code>&lt;#VIEW&gt;</code> 表示模板的实例。请注意，每个组件都有自己的 <code>&lt;#VIEW&gt;</code> 。</p><p translation-origin="off">The <code>&lt;#VIEW&gt;</code> here represents an instance of a template. Notice that each component has its own <code>&lt;#VIEW&gt;</code>.</p><p translation-result="on">了解此结构可以告知您如何提供和注入服务，并完全控制服务的可见性。</p><p translation-origin="off">Knowledge of this structure can inform how you provide and inject your services, and give you complete control of service visibility.</p><p translation-result="on">现在，考虑 <code>&lt;app-root&gt;</code> 只注入了 <code>FlowerService</code> ：</p><p translation-origin="off">Now, consider that <code>&lt;app-root&gt;</code> simply injects the <code>FlowerService</code>:</p><code-example path="providers-viewproviders/src/app/app.component.1.ts" header="providers-viewproviders/src/app/app.component.ts" region="injection" ng-version="9.0.0-rc.11"><div style="display:none">export class AppComponent { constructor(public flower: FlowerService) {} }</div><header class="ng-star-inserted">providers-viewproviders/src/app/app.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/app.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AppComponent</span><span class="pln">  </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">public</span><span class="pln"> flower</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">将绑定添加到 <code>&lt;app-root&gt;</code> 模板来将结果可视化：</p><p translation-origin="off">Add a binding to the <code>&lt;app-root&gt;</code> template to visualize the result:</p><code-example path="providers-viewproviders/src/app/app.component.html" header="providers-viewproviders/src/app/app.component.html" region="binding-flower" ng-version="9.0.0-rc.11"><div style="display:none">&lt;p&gt;Emoji from FlowerService: {{flower.emoji}}&lt;/p&gt;</div><header class="ng-star-inserted">providers-viewproviders/src/app/app.component.html</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/app.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from FlowerService: {{flower.emoji}}</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">该视图中的输出为：</p><p translation-origin="off">The output in the view would be:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">Emoji from FlowerService: 🌺</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="typ">Emoji</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">:</span><span class="pln"> </span><span class="pun">🌺</span></code>
    </pre></aio-code></code-example><p translation-result="on">在逻辑树中，这可以表示成如下形式：</p><p translation-origin="off">In the logical tree, this would be represented as follows:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(FlowerService) flower=&gt;"🌺"&gt; &lt;#VIEW&gt; &lt;p&gt;Emoji from FlowerService: {{flower.emoji}} (🌺)&lt;/p&gt; &lt;app-child&gt; &lt;#VIEW&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">FlowerService</span><span class="pln">) </span><span class="atn">flower</span><span class="tag">=&gt;</span><span class="pln">"🌺"&gt;
  &lt;#VIEW&gt;

    </span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from FlowerService: {{flower.emoji}} (🌺)</span><span class="tag">&lt;/p&gt;</span><span class="pln">

    </span><span class="tag">&lt;app-child&gt;</span><span class="pln">
      &lt;#VIEW&gt;
      &lt;/#VIEW&gt;
     </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">当 <code>&lt;app-root&gt;</code> 请求 <code>FlowerService</code> 时，注入器的工作就是解析 <code>FlowerService</code> 令牌。令牌的解析分为两个阶段：</p><p translation-origin="off">When <code>&lt;app-root&gt;</code> requests the <code>FlowerService</code>, it is the injector's job to resolve the <code>FlowerService</code> token. The resolution of the token happens in two phases:</p><ol><li><p translation-result="on">注入器确定逻辑树中搜索的开始位置和结束位置。注入程序从起始位置开始，并在逻辑树的每个级别上查找令牌。如果找到令牌，则将其返回。</p><p translation-origin="off">The injector determines the starting location in the logical tree and an ending location of the search. The injector begins with the starting location and looks for the token at each level in the logical tree. If the token is found it is returned.</p></li></ol><ol start="2"><li><p translation-result="on">如果未找到令牌，则注入程序将寻找最接近的父 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 委派该请求。</p><p translation-origin="off">If the token is not found, the injector looks for the closest parent <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> to delegate the request to.</p></li></ol><p translation-result="on">在这个例子中，约束为：</p><p translation-origin="off">In the example case, the constraints are:</p><ol><li><p translation-result="on">从属于 <code>&lt;app-root&gt;</code> 的 <code>&lt;#VIEW&gt;</code> 开始，并结束于 <code>&lt;app-root&gt;</code> 。</p><p translation-origin="off">Start with <code>&lt;#VIEW&gt;</code> belonging to <code>&lt;app-root&gt;</code> and end with <code>&lt;app-root&gt;</code>.</p></li></ol><ul><li><p translation-result="on">通常，搜索的起点就是注入点。但是，在这个例子中，<code>&lt;app-root&gt;</code> <code>@<a href="api/core/Component" class="code-anchor">Component</a></code> 的特殊之处在于它们还包括自己的 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code>，这就是为什么搜索从 <code>&lt;app-root&gt;</code> 的 <code>&lt;#VIEW&gt;</code> 开始的原因。（对于匹配同一位置的指令，情况却并非如此）。</p><p translation-origin="off">Normally the starting point for search is at the point of injection. However, in this case <code>&lt;app-root&gt;</code> <code>@<a href="api/core/Component" class="code-anchor">Component</a></code>s are special in that they also include their own <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code>, which is why the search starts at <code>&lt;#VIEW&gt;</code> belonging to <code>&lt;app-root&gt;</code>. (This would not be the case for a directive matched at the same location).</p></li></ul><ul><li><p translation-result="on">结束位置恰好与组件本身相同，因为它就是此应用程序中最顶层的组件。</p><p translation-origin="off">The ending location just happens to be the same as the component itself, because it is the topmost component in this application.</p></li></ul><ol start="2"><li><p translation-result="on">当在 <code>ElementInjector</code> 中找不到注入令牌时，就用 <code>AppModule</code> 充当后备注入器。</p><p translation-origin="off">The <code>AppModule</code> acts as the fallback injector when the injection token can't be found in the <code>ElementInjector</code>s.</p></li></ol><h3 id="using-the-providers-array" translation-result="on">使用 <code>providers</code> 数组<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#using-the-providers-array"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="using-the-providers-array">Using the <code>providers</code> array<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#using-the-providers-array"><i class="material-icons">link</i></a></h3><p translation-result="on">现在，在 <code>ChildComponent</code> 类中，为 <code>FlowerService</code> 添加一个提供者，以便在接下来的小节中演示更复杂的解析规则：</p><p translation-origin="off">Now, in the <code>ChildComponent</code> class, add a provider for <code>FlowerService</code> to demonstrate more complex resolution rules in the upcoming sections:</p><code-example path="providers-viewproviders/src/app/child/child.component.1.ts" header="providers-viewproviders/src/app/child.component.ts" region="flowerservice" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-child', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './child.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: ['./child.component.css'], // use the providers array to provide a service providers: [{ provide: FlowerService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🌻' } }] }) export class ChildComponent { // inject the service constructor( public flower: FlowerService) { } }</div><header class="ng-star-inserted">providers-viewproviders/src/app/child.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/child.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-child'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./child.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">'./child.component.css'</span><span class="pun">],</span><span class="pln">
  </span><span class="com">// use the providers array to provide a service</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🌻'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">

</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ChildComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// inject the service</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> flower</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">现在，在 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 装饰器中提供了 <code>FlowerService</code> ，当 <code>&lt;app-child&gt;</code> 请求该服务时，注入器仅需要查找 <code>&lt;app-child&gt;</code> 自己的 <code>ElementInjector</code> 。不必再通过注入器树继续搜索。</p><p translation-origin="off">Now that the <code>FlowerService</code> is provided in the <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> decorator, when the <code>&lt;app-child&gt;</code> requests the service, the injector has only to look as far as the <code>&lt;app-child&gt;</code>'s own <code>ElementInjector</code>. It won't have to continue the search any further through the injector tree.</p><p translation-result="on">下一步是将绑定添加到 <code>ChildComponent</code> 模板。</p><p translation-origin="off">The next step is to add a binding to the <code>ChildComponent</code> template.</p><code-example path="providers-viewproviders/src/app/child/child.component.html" header="providers-viewproviders/src/app/child.component.html" region="flower-binding" ng-version="9.0.0-rc.11"><div style="display:none">&lt;p&gt;Emoji from FlowerService: {{flower.emoji}}&lt;/p&gt;</div><header class="ng-star-inserted">providers-viewproviders/src/app/child.component.html</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/child.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from FlowerService: {{flower.emoji}}</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">要渲染新的值，请在 <code>AppComponent</code> 模板的底部添加 <code>&lt;app-child&gt;</code> ，以便其视图也显示向日葵：</p><p translation-origin="off">To render the new values, add <code>&lt;app-child&gt;</code> to the bottom of the <code>AppComponent</code> template so the view also displays the sunflower:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">Child <a href="api/core/Component" class="code-anchor">Component</a> Emoji from FlowerService: 🌻</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="typ">Child</span><span class="pln"> </span><a href="api/core/Component" class="code-anchor"><span class="typ">Component</span></a><span class="pln">
</span><span class="typ">Emoji</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">:</span><span class="pln"> </span><span class="pun">🌻</span></code>
    </pre></aio-code></code-example><p translation-result="on">在逻辑树中，可以把它表示成这样：</p><p translation-origin="off">In the logical tree, this would be represented as follows:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(FlowerService) flower=&gt;"🌺"&gt; &lt;#VIEW&gt; &lt;p&gt;Emoji from FlowerService: {{flower.emoji}} (🌺)&lt;/p&gt; &lt;app-child @Provide(FlowerService="🌻") @<a href="api/core/Inject" class="code-anchor">Inject</a>(FlowerService)=&gt;"🌻"&gt; &lt;!-- search ends here --&gt; &lt;#VIEW&gt; &lt;!-- search starts here --&gt; &lt;h2&gt;Parent <a href="api/core/Component" class="code-anchor">Component</a>&lt;/h2&gt; &lt;p&gt;Emoji from FlowerService: {{flower.emoji}} (🌻)&lt;/p&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">FlowerService</span><span class="pln">) </span><span class="atn">flower</span><span class="tag">=&gt;</span><span class="pln">"🌺"&gt;
  &lt;#VIEW&gt;

    </span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from FlowerService: {{flower.emoji}} (🌺)</span><span class="tag">&lt;/p&gt;</span><span class="pln">

    </span><span class="tag">&lt;app-child</span><span class="pln"> @</span><span class="atn">Provide</span><span class="pln">(</span><span class="atn">FlowerService</span><span class="pun">=</span><span class="atv">"🌻"</span><span class="pln">)
               @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">FlowerService</span><span class="pln">)</span><span class="tag">=&gt;</span><span class="pln">"🌻"&gt; </span><span class="com">&lt;!-- search ends here --&gt;</span><span class="pln">
      &lt;#VIEW&gt; </span><span class="com">&lt;!-- search starts here --&gt;</span><span class="pln">

        </span><span class="tag">&lt;h2&gt;</span><span class="pln">Parent </span><a href="api/core/Component" class="code-anchor"><span class="pln">Component</span></a><span class="tag">&lt;/h2&gt;</span><span class="pln">

        </span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from FlowerService: {{flower.emoji}} (🌻)</span><span class="tag">&lt;/p&gt;</span><span class="pln">

      &lt;/#VIEW&gt;
     </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">当 <code>&lt;app-child&gt;</code> 请求 <code>FlowerService</code> 时，注入器从 <code>&lt;app-child&gt;</code> 的 <code>&lt;#VIEW&gt;</code> 开始搜索（包括 <code>&lt;#VIEW&gt;</code> ，因为它是从 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 注入的），并到 <code>&lt;app-child&gt;</code> 结束。在这个例子中， <code>FlowerService</code> 在 <code>&lt;app-child&gt;</code> 的 <code>providers</code> 数组中解析为向日葵🌻。注入器不必在注入器树中进一步查找。一旦找到 <code>FlowerService</code> ，它便停止运行，再也看不到🌺（红芙蓉）。</p><p translation-origin="off">When <code>&lt;app-child&gt;</code> requests the <code>FlowerService</code>, the injector begins its search at the <code>&lt;#VIEW&gt;</code> belonging to <code>&lt;app-child&gt;</code> (<code>&lt;#VIEW&gt;</code> is included because it is injected from <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code>) and ends with <code>&lt;app-child&gt;</code>. In this case, the <code>FlowerService</code> is resolved in the <code>&lt;app-child&gt;</code>'s <code>providers</code> array with sunflower 🌻. The injector doesn't have to look any further in the injector tree. It stops as soon as it finds the <code>FlowerService</code> and never sees the 🌺 (red hibiscus).</p><a id="use-view-providers"></a><h3 id="using-the-viewproviders-array" translation-result="on">使用 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#using-the-viewproviders-array"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="using-the-viewproviders-array">Using the <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#using-the-viewproviders-array"><i class="material-icons">link</i></a></h3><p translation-result="on">使用 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组是在 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 装饰器中提供服务的另一种方法。使用 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 使服务在 <code>&lt;#VIEW&gt;</code> 中可见。</p><p translation-origin="off">Use the <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array as another way to provide services in the <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> decorator. Using <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> makes services visible in the <code>&lt;#VIEW&gt;</code>.</p><div class="is-helpful alert"><p translation-result="on">除了使用 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组外，其他步骤与使用 <code>providers</code> 数组相同。</p><p translation-origin="off">The steps are the same as using the <code>providers</code> array, with the exception of using the <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array instead.</p><p translation-result="on">有关这些步骤的说明，请继续本节。如果你可以自行设置，请跳至<a href="guide/hierarchical-dependency-injection#modify-visibility">修改服务可用性</a> 一节。</p><p translation-origin="off">For step-by-step instructions, continue with this section. If you can set it up on your own, skip ahead to <a href="guide/hierarchical-dependency-injection#modify-visibility">Modifying service availability</a>.</p></div><p translation-result="on">该示例应用程序具有第二个服务 <code>AnimalService</code> 来演示 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 。</p><p translation-origin="off">The example app features a second service, the <code>AnimalService</code> to demonstrate <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code>.</p><p translation-result="on">首先，创建一个 <code>AnimalService</code> 与 <code>emoji</code> 的🐳（鲸鱼）属性：</p><p translation-origin="off">First, create an <code>AnimalService</code> with an <code>emoji</code> property of 🐳 (whale):</p><code-example path="providers-viewproviders/src/app/animal.service.ts" header="providers-viewproviders/src/app/animal.service.ts" region="animal-service" ng-version="9.0.0-rc.11"><div style="display:none">import { <a href="api/core/Injectable" class="code-anchor">Injectable</a> } from '@angular/core'; @<a href="api/core/Injectable" class="code-anchor">Injectable</a>({ <a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>: 'root' }) export class AnimalService { emoji = '🐳'; }</div><header class="ng-star-inserted">providers-viewproviders/src/app/animal.service.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/animal.service.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Injectable" class="code-anchor"><span class="typ">Injectable</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Injectable" class="code-anchor"><span class="lit">Injectable</span></a><span class="pun">({</span><span class="pln">
  </span><a href="api/core/Injectable#providedIn" class="code-anchor"><span class="pln">providedIn</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'root'</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  emoji </span><span class="pun">=</span><span class="pln"> </span><span class="str">'🐳'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">遵循与 <code>FlowerService</code> 相同的模式，将 <code>AnimalService</code> 注入 <code>AppComponent</code> 类：</p><p translation-origin="off">Following the same pattern as with the <code>FlowerService</code>, inject the <code>AnimalService</code> in the <code>AppComponent</code> class:</p><code-example path="providers-viewproviders/src/app/app.component.ts" header="providers-viewproviders/src/app/app.component.ts" region="inject-animal-service" ng-version="9.0.0-rc.11"><div style="display:none">export class AppComponent { constructor(public flower: FlowerService, public animal: AnimalService) {} }</div><header class="ng-star-inserted">providers-viewproviders/src/app/app.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/app.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AppComponent</span><span class="pln">  </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">public</span><span class="pln"> flower</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> animal</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><div class="alert is-helpful"><p translation-result="on"><strong>注意：</strong>您可以保留所有与 <code>FlowerService</code> 相关的代码，因为它可以与 <code>AnimalService</code> 进行比较。</p><p translation-origin="off"><strong>Note:</strong> You can leave all the <code>FlowerService</code> related code in place as it will allow a comparison with the <code>AnimalService</code>.</p></div><p translation-result="on">添加一个 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组，并将 <code>AnimalService</code> 也注入到 <code>&lt;app-child&gt;</code> 类中，但是给 <code>emoji</code> 一个不同的值。在这里，它的值为🐶（小狗）。</p><p translation-origin="off">Add a <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array and inject the <code>AnimalService</code> in the <code>&lt;app-child&gt;</code> class, too, but give <code>emoji</code> a different value. Here, it has a value of 🐶 (puppy).</p><code-example path="providers-viewproviders/src/app/child/child.component.ts" header="providers-viewproviders/src/app/child.component.ts" region="provide-animal-service" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-child', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './child.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: ['./child.component.css'], // provide services providers: [{ provide: FlowerService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🌻' } }], <a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a>: [{ provide: AnimalService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🐶' } }] }) export class ChildComponent { // inject service constructor( public flower: FlowerService, public animal: AnimalService) { } }</div><header class="ng-star-inserted">providers-viewproviders/src/app/child.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/child.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-child'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./child.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">'./child.component.css'</span><span class="pun">],</span><span class="pln">
  </span><span class="com">// provide services</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🌻'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}],</span><span class="pln">
  </span><a href="api/core/Component#viewProviders" class="code-anchor"><span class="pln">viewProviders</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🐶'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">

</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ChildComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// inject service</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> flower</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> animal</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">将绑定添加到 <code>ChildComponent</code> 和 <code>AppComponent</code> 模板。在 <code>ChildComponent</code> 模板中，添加以下绑定：</p><p translation-origin="off">Add bindings to the <code>ChildComponent</code> and the <code>AppComponent</code> templates. In the <code>ChildComponent</code> template, add the following binding:</p><code-example path="providers-viewproviders/src/app/child/child.component.html" header="providers-viewproviders/src/app/child.component.html" region="animal-binding" ng-version="9.0.0-rc.11"><div style="display:none">&lt;p&gt;Emoji from AnimalService: {{animal.emoji}}&lt;/p&gt;</div><header class="ng-star-inserted">providers-viewproviders/src/app/child.component.html</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/child.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}}</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">此外，将其添加到 <code>AppComponent</code> 模板：</p><p translation-origin="off">Additionally, add the same to the <code>AppComponent</code> template:</p><code-example path="providers-viewproviders/src/app/app.component.html" header="providers-viewproviders/src/app/app.component.html" region="binding-animal" ng-version="9.0.0-rc.11"><div style="display:none">&lt;p&gt;Emoji from AnimalService: {{animal.emoji}}&lt;/p&gt;</div><header class="ng-star-inserted">providers-viewproviders/src/app/app.component.html</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/app.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}}</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">现在，您应该在浏览器中看到两个值：</p><p translation-origin="off">Now you should see both values in the browser:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">AppComponent Emoji from AnimalService: 🐳 Child <a href="api/core/Component" class="code-anchor">Component</a> Emoji from AnimalService: 🐶</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="typ">AppComponent</span><span class="pln">
</span><span class="typ">Emoji</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">:</span><span class="pln"> </span><span class="pun">🐳</span><span class="pln">

</span><span class="typ">Child</span><span class="pln"> </span><a href="api/core/Component" class="code-anchor"><span class="typ">Component</span></a><span class="pln">
</span><span class="typ">Emoji</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">:</span><span class="pln"> </span><span class="pun">🐶</span></code>
    </pre></aio-code></code-example><p translation-result="on">此 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 示例的逻辑树如下：</p><p translation-origin="off">The logic tree for this example of <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> is as follows:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService) animal=&gt;"🐳"&gt; &lt;#VIEW&gt; &lt;app-child&gt; &lt;#VIEW @Provide(AnimalService="🐶") @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService=&gt;"🐶")&gt; &lt;!-- ^^using <a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a> means AnimalService is available in &lt;#VIEW&gt;--&gt; &lt;p&gt;Emoji from AnimalService: {{animal.emoji}} (🐶)&lt;/p&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">AnimalService</span><span class="pln">) </span><span class="atn">animal</span><span class="tag">=&gt;</span><span class="pln">"🐳"&gt;
  &lt;#VIEW&gt;
    </span><span class="tag">&lt;app-child&gt;</span><span class="pln">
      &lt;#VIEW
       @Provide(AnimalService="🐶")
       @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(AnimalService=&gt;"🐶")&gt;

       </span><span class="com">&lt;!-- ^^using </span><a href="api/core/Component#viewProviders" class="code-anchor"><span class="com">viewProviders</span></a><span class="com"> means AnimalService is available in &lt;#VIEW&gt;--&gt;</span><span class="pln">

       </span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}} (🐶)</span><span class="tag">&lt;/p&gt;</span><span class="pln">

      &lt;/#VIEW&gt;
     </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">与 <code>FlowerService</code> 示例一样， <code>&lt;app-child&gt;</code> <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 装饰器中提供了 <code>AnimalService</code>。这意味着，由于注入器首先在组件的 <code>ElementInjector</code> 中查找，因此它将找到 <code>AnimalService</code> 的值 🐶（小狗）。它不需要继续搜索 <code>ElementInjector</code> 树，也不需要搜索 <code>ModuleInjector</code> 。</p><p translation-origin="off">Just as with the <code>FlowerService</code> example, the <code>AnimalService</code> is provided in the <code>&lt;app-child&gt;</code> <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> decorator. This means that since the injector first looks in the <code>ElementInjector</code> of the component, it finds the <code>AnimalService</code> value of 🐶 (puppy). It doesn't need to continue searching the <code>ElementInjector</code> tree, nor does it need to search the <code>ModuleInjector</code>.</p><h3 id="providers-vs-viewproviders" translation-result="on"><code>providers</code> 与 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#providers-vs-viewproviders"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="providers-vs-viewproviders"><code>providers</code> vs. <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#providers-vs-viewproviders"><i class="material-icons">link</i></a></h3><p translation-result="on">为了看清 <code>providers</code> 和 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 的差异，请在示例中添加另一个组件，并将其命名为 <code>InspectorComponent</code> 。 <code>InspectorComponent</code> 将是 <code>ChildComponent</code> 的子 <code>ChildComponent</code> 。在 <code>inspector.component.ts</code> 中，将 <code>FlowerService</code> 和 <code>AnimalService</code> 注入构造函数中：</p><p translation-origin="off">To see the difference between using <code>providers</code> and <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code>, add another component to the example and call it <code>InspectorComponent</code>. <code>InspectorComponent</code> will be a child of the <code>ChildComponent</code>. In <code>inspector.component.ts</code>, inject the <code>FlowerService</code> and <code>AnimalService</code> in the constructor:</p><code-example path="providers-viewproviders/src/app/inspector/inspector.component.ts" header="providers-viewproviders/src/app/inspector/inspector.component.ts" region="injection" ng-version="9.0.0-rc.11"><div style="display:none">export class InspectorComponent { constructor(public flower: FlowerService, public animal: AnimalService) { } }</div><header class="ng-star-inserted">providers-viewproviders/src/app/inspector/inspector.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/inspector/inspector.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">InspectorComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">public</span><span class="pln"> flower</span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> animal</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">您不需要 <code>providers</code> 或 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组。接下来，在 <code>inspector.component.html</code> 中，从以前的组件中添加相同的 html：</p><p translation-origin="off">You do not need a <code>providers</code> or <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array. Next, in <code>inspector.component.html</code>, add the same markup from previous components:</p><code-example path="providers-viewproviders/src/app/inspector/inspector.component.html" header="providers-viewproviders/src/app/inspector/inspector.component.html" region="binding" ng-version="9.0.0-rc.11"><div style="display:none">&lt;p&gt;Emoji from FlowerService: {{flower.emoji}}&lt;/p&gt; &lt;p&gt;Emoji from AnimalService: {{animal.emoji}}&lt;/p&gt;</div><header class="ng-star-inserted">providers-viewproviders/src/app/inspector/inspector.component.html</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/inspector/inspector.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from FlowerService: {{flower.emoji}}</span><span class="tag">&lt;/p&gt;</span><span class="pln">
</span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}}</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">别忘了将 <code>InspectorComponent</code> 添加到 <code>AppModule</code> <code>declarations</code> 数组。</p><p translation-origin="off">Remember to add the <code>InspectorComponent</code> to the <code>AppModule</code> <code>declarations</code> array.</p><code-example path="providers-viewproviders/src/app/app.module.ts" header="providers-viewproviders/src/app/app.module.ts" region="appmodule" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/NgModule" class="code-anchor">NgModule</a>({ imports: [ <a href="api/platform-browser/BrowserModule" class="code-anchor">BrowserModule</a>, <a href="api/forms/FormsModule" class="code-anchor">FormsModule</a> ], declarations: [ AppComponent, ChildComponent, InspectorComponent ], bootstrap: [ AppComponent ], providers: [] }) export class AppModule { }</div><header class="ng-star-inserted">providers-viewproviders/src/app/app.module.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/app.module.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/NgModule" class="code-anchor"><span class="lit">NgModule</span></a><span class="pun">({</span><span class="pln">
  imports</span><span class="pun">:</span><span class="pln">      </span><span class="pun">[</span><span class="pln"> </span><a href="api/platform-browser/BrowserModule" class="code-anchor"><span class="typ">BrowserModule</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/forms/FormsModule" class="code-anchor"><span class="typ">FormsModule</span></a><span class="pln"> </span><span class="pun">],</span><span class="pln">
  declarations</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">AppComponent</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ChildComponent</span><span class="pun">,</span><span class="pln"> </span><span class="typ">InspectorComponent</span><span class="pln"> </span><span class="pun">],</span><span class="pln">
  bootstrap</span><span class="pun">:</span><span class="pln">    </span><span class="pun">[</span><span class="pln"> </span><span class="typ">AppComponent</span><span class="pln"> </span><span class="pun">],</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AppModule</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">接下来，确保您的 <code>child.component.html</code> 包含以下内容：</p><p translation-origin="off">Next, make sure your <code>child.component.html</code> contains the following:</p><code-example path="providers-viewproviders/src/app/child/child.component.html" header="providers-viewproviders/src/app/child/child.component.html" region="child-component" ng-version="9.0.0-rc.11"><div style="display:none">&lt;p&gt;Emoji from FlowerService: {{flower.emoji}}&lt;/p&gt; &lt;p&gt;Emoji from AnimalService: {{animal.emoji}}&lt;/p&gt; &lt;div class="container"&gt; &lt;h3&gt;Content projection&lt;/h3&gt; &lt;ng-content&gt;&lt;/ng-content&gt; &lt;/div&gt; &lt;h3&gt;Inside the view&lt;/h3&gt; &lt;app-inspector&gt;&lt;/app-inspector&gt;</div><header class="ng-star-inserted">providers-viewproviders/src/app/child/child.component.html</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/child/child.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from FlowerService: {{flower.emoji}}</span><span class="tag">&lt;/p&gt;</span><span class="pln">
</span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}}</span><span class="tag">&lt;/p&gt;</span><span class="pln">

</span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"container"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;h3&gt;</span><span class="pln">Content projection</span><span class="tag">&lt;/h3&gt;</span><span class="pln">
	</span><span class="tag">&lt;ng-content&gt;&lt;/ng-content&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span><span class="pln">

</span><span class="tag">&lt;h3&gt;</span><span class="pln">Inside the view</span><span class="tag">&lt;/h3&gt;</span><span class="pln">
</span><span class="tag">&lt;app-inspector&gt;&lt;/app-inspector&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">前两行带有绑定，来自之前的步骤。新的部分是 <code>&lt;ng-content&gt;</code> 和 <code>&lt;app-inspector&gt;</code>。 <code>&lt;ng-content&gt;</code> 允许您投影内容， <code>ChildComponent</code> 模板中的 <code>&lt;app-inspector&gt;</code> 使 <code>InspectorComponent</code> 成为 <code>ChildComponent</code> 的子组件。</p><p translation-origin="off">The first two lines, with the bindings, are there from previous steps. The new parts are <code>&lt;ng-content&gt;</code> and <code>&lt;app-inspector&gt;</code>. <code>&lt;ng-content&gt;</code> allows you to project content, and <code>&lt;app-inspector&gt;</code> inside the <code>ChildComponent</code> template makes the <code>InspectorComponent</code> a child component of <code>ChildComponent</code>.</p><p translation-result="on">接下来，将以下内容添加到 <code>app.component.html</code> 中以利用内容投影的优势。</p><p translation-origin="off">Next, add the following to <code>app.component.html</code> to take advantage of content projection.</p><code-example path="providers-viewproviders/src/app/app.component.html" header="providers-viewproviders/src/app/app.component.html" region="content-projection" ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-child&gt;&lt;app-inspector&gt;&lt;/app-inspector&gt;&lt;/app-child&gt;</div><header class="ng-star-inserted">providers-viewproviders/src/app/app.component.html</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from providers-viewproviders/src/app/app.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-child&gt;&lt;app-inspector&gt;&lt;/app-inspector&gt;&lt;/app-child&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">现在，浏览器将呈现以下内容，为简洁起见，省略了前面的示例：</p><p translation-origin="off">The browser now renders the following, omitting the previous examples for brevity:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">//...Omitting <a href="api/service-worker/UpdateActivatedEvent#previous" class="code-anchor">previous</a> examples. The following applies to this section. Content projection: This is coming from content. Doesn't get to see puppy because the puppy is declared inside the view only. Emoji from FlowerService: 🌻 Emoji from AnimalService: 🐳 Emoji from FlowerService: 🌻 Emoji from AnimalService: 🐶</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="com">//...Omitting </span><a href="api/service-worker/UpdateActivatedEvent#previous" class="code-anchor"><span class="com">previous</span></a><span class="com"> examples. The following applies to this section.</span><span class="pln">

</span><span class="typ">Content</span><span class="pln"> projection</span><span class="pun">:</span><span class="pln"> </span><span class="typ">This</span><span class="pln"> </span><span class="kwd">is</span><span class="pln"> coming </span><span class="kwd">from</span><span class="pln"> content</span><span class="pun">.</span><span class="pln"> </span><span class="typ">Doesn</span><span class="str">'t get to see
puppy because the puppy is declared inside the view only.

Emoji from FlowerService: 🌻
Emoji from AnimalService: 🐳

Emoji from FlowerService: 🌻
Emoji from AnimalService: 🐶</span></code>
    </pre></aio-code></code-example><p translation-result="on">这四个绑定说明了 <code>providers</code> 和 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 之间的区别。由于🐶（小狗）在&lt;#VIEW&gt;中声明，因此投影内容不可见。投影的内容中会看到🐳（鲸鱼）。</p><p translation-origin="off">These four bindings demonstrate the difference between <code>providers</code> and <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code>. Since the 🐶 (puppy) is declared inside the &lt;#VIEW&gt;, it isn't visible to the projected content. Instead, the projected content sees the 🐳 (whale).</p><p translation-result="on">但是下一部分， <code>InspectorComponent</code> 是 <code>ChildComponent</code> 的子组件， <code>InspectorComponent</code> 在 <code>&lt;#VIEW&gt;</code> 内部，因此当它请求 <code>AnimalService</code> 时，它会看到🐶（小狗）。</p><p translation-origin="off">The next section though, where <code>InspectorComponent</code> is a child component of <code>ChildComponent</code>, <code>InspectorComponent</code> is inside the <code>&lt;#VIEW&gt;</code>, so when it asks for the <code>AnimalService</code>, it sees the 🐶 (puppy).</p><p translation-result="on">逻辑树中的 <code>AnimalService</code> 如下所示：</p><p translation-origin="off">The <code>AnimalService</code> in the logical tree would look like this:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService) animal=&gt;"🐳"&gt; &lt;#VIEW&gt; &lt;app-child&gt; &lt;#VIEW @Provide(AnimalService="🐶") @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService=&gt;"🐶")&gt; &lt;!-- ^^using <a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a> means AnimalService is available in &lt;#VIEW&gt;--&gt; &lt;p&gt;Emoji from AnimalService: {{animal.emoji}} (🐶)&lt;/p&gt; &lt;app-inspector&gt; &lt;p&gt;Emoji from AnimalService: {{animal.emoji}} (🐶)&lt;/p&gt; &lt;/app-inspector&gt; &lt;/#VIEW&gt; &lt;app-inspector&gt; &lt;#VIEW&gt; &lt;p&gt;Emoji from AnimalService: {{animal.emoji}} (🐳)&lt;/p&gt; &lt;/#VIEW&gt; &lt;/app-inspector&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">AnimalService</span><span class="pln">) </span><span class="atn">animal</span><span class="tag">=&gt;</span><span class="pln">"🐳"&gt;
  &lt;#VIEW&gt;
    </span><span class="tag">&lt;app-child&gt;</span><span class="pln">
      &lt;#VIEW
       @Provide(AnimalService="🐶")
       @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(AnimalService=&gt;"🐶")&gt;

       </span><span class="com">&lt;!-- ^^using </span><a href="api/core/Component#viewProviders" class="code-anchor"><span class="com">viewProviders</span></a><span class="com"> means AnimalService is available in &lt;#VIEW&gt;--&gt;</span><span class="pln">

       </span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}} (🐶)</span><span class="tag">&lt;/p&gt;</span><span class="pln">

       </span><span class="tag">&lt;app-inspector&gt;</span><span class="pln">

        </span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}} (🐶)</span><span class="tag">&lt;/p&gt;</span><span class="pln">

       </span><span class="tag">&lt;/app-inspector&gt;</span><span class="pln">
      &lt;/#VIEW&gt;
      </span><span class="tag">&lt;app-inspector&gt;</span><span class="pln">
        &lt;#VIEW&gt;

          </span><span class="tag">&lt;p&gt;</span><span class="pln">Emoji from AnimalService: {{animal.emoji}} (🐳)</span><span class="tag">&lt;/p&gt;</span><span class="pln">

        &lt;/#VIEW&gt;
      </span><span class="tag">&lt;/app-inspector&gt;</span><span class="pln">
     </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>&lt;app-inspector&gt;</code> 的投影内容中看到了🐳（鲸鱼），而不是🐶（小狗），因为🐶（小狗）在 <code>&lt;app-child&gt;</code> 的 <code>&lt;#VIEW&gt;</code> 中。如果 <code>&lt;app-inspector&gt;</code> 也位于 <code>&lt;#VIEW&gt;</code> 则只能看到🐶（小狗）。</p><p translation-origin="off">The projected content of <code>&lt;app-inspector&gt;</code> sees the 🐳 (whale), not the 🐶 (puppy), because the 🐶 (puppy) is inside the <code>&lt;app-child&gt;</code> <code>&lt;#VIEW&gt;</code>. The <code>&lt;app-inspector&gt;</code> can only see the 🐶 (puppy) if it is also within the <code>&lt;#VIEW&gt;</code>.</p><a id="modify-visibility"></a><h2 id="modifying-service-visibility" translation-result="on">修改服务可见性<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#modifying-service-visibility"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="modifying-service-visibility">Modifying service visibility<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#modifying-service-visibility"><i class="material-icons">link</i></a></h2><p translation-result="on">本节讲的是如何使用可见性修饰符 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> ， <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code> 和 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 来限制 <code>ElementInjector</code> 的开始和结束范围。</p><p translation-origin="off">This section describes how to limit the scope of the beginning and ending <code>ElementInjector</code> using the visibility decorators <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code>, <code>@<a href="api/core/Self" class="code-anchor">Self</a>()</code>, and <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>.</p><h3 id="visibility-of-provided-tokens" translation-result="on">提供者令牌的可见性<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#visibility-of-provided-tokens"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="visibility-of-provided-tokens">Visibility of provided tokens<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#visibility-of-provided-tokens"><i class="material-icons">link</i></a></h3><p translation-result="on">可见性装饰器影响搜索注入令牌时在逻辑树中开始和结束的位置。为此，要将可见性装饰器放置在注入点，即 <code>constructor()</code> ，而不是在声明点。</p><p translation-origin="off">Visibility decorators influence where the search for the injection token begins and ends in the logic tree. To do this, place visibility decorators at the point of injection, that is, the <code>constructor()</code>, rather than at a point of declaration.</p><p translation-result="on">为了修改该注入器从哪里开始寻找 <code>FlowerService</code>，把 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 加到 <code>&lt;app-child&gt;</code> 的 <code>@<a href="api/core/Inject" class="code-anchor">Inject</a></code> 声明 <code>FlowerService</code> 中。该声明在 <code>&lt;app-child&gt;</code> 构造函数中，如 <code>child.component.ts</code> 所示：</p><p translation-origin="off">To alter where the injector starts looking for <code>FlowerService</code>, add <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> to the <code>&lt;app-child&gt;</code> <code>@<a href="api/core/Inject" class="code-anchor">Inject</a></code> declaration for the <code>FlowerService</code>. This declaration is in the <code>&lt;app-child&gt;</code> constructor as shown in <code>child.component.ts</code>:</p><code-example language="typescript=" ng-version="9.0.0-rc.11"><div style="display:none">constructor(@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() public flower : FlowerService) { }</div><aio-code><pre class="lang-typescript= prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/SkipSelf" class="code-anchor"><span class="lit">SkipSelf</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> flower </span><span class="pun">:</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">使用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>，<code>&lt;app-child&gt;</code> 注入器不会寻找自身来获取 <code>FlowerService</code>。相反，喷射器开始在 <code>&lt;app-root&gt;</code> 的 <code>ElementInjector</code> 中寻找 <code>FlowerService</code>，在那里它什么也没找到。 然后，它返回到 <code>&lt;app-child&gt;</code> 的 <code>ModuleInjector</code> 并找到🌺（红芙蓉）值，这是可用的，因为 <code>&lt;app-child&gt;</code> <code>ModuleInjector</code> 和 <code>&lt;app-root&gt;</code> <code>ModuleInjector</code> 被展开成了一个 <code>ModuleInjector</code> 。因此，UI 将呈现以下内容：</p><p translation-origin="off">With <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>, the <code>&lt;app-child&gt;</code> injector doesn't look to itself for the <code>FlowerService</code>. Instead, the injector starts looking for the <code>FlowerService</code> at the <code>&lt;app-root&gt;</code>'s <code>ElementInjector</code>, where it finds nothing. Then, it goes back to the <code>&lt;app-child&gt;</code> <code>ModuleInjector</code> and finds the 🌺 (red hibiscus) value, which is available because the <code>&lt;app-child&gt;</code> <code>ModuleInjector</code> and the <code>&lt;app-root&gt;</code> <code>ModuleInjector</code> are flattened into one <code>ModuleInjector</code>. Thus, the UI renders the following:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">Emoji from FlowerService: 🌺</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="typ">Emoji</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="typ">FlowerService</span><span class="pun">:</span><span class="pln"> </span><span class="pun">🌺</span></code>
    </pre></aio-code></code-example><p translation-result="on">在逻辑树中，这种情况可能如下所示：</p><p translation-origin="off">In a logical tree, this same idea might look like this:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(FlowerService) flower=&gt;"🌺"&gt; &lt;#VIEW&gt; &lt;app-child @Provide(FlowerService="🌻")&gt; &lt;#VIEW @<a href="api/core/Inject" class="code-anchor">Inject</a>(FlowerService, <a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>)=&gt;"🌺"&gt; &lt;!-- With <a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>, the injector looks to the next injector up the tree --&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">FlowerService</span><span class="pln">) </span><span class="atn">flower</span><span class="tag">=&gt;</span><span class="pln">"🌺"&gt;
  &lt;#VIEW&gt;
    </span><span class="tag">&lt;app-child</span><span class="pln"> @</span><span class="atn">Provide</span><span class="pln">(</span><span class="atn">FlowerService</span><span class="pun">=</span><span class="atv">"🌻"</span><span class="pln">)</span><span class="tag">&gt;</span><span class="pln">
      &lt;#VIEW @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(FlowerService, </span><a href="api/core/SkipSelf" class="code-anchor"><span class="pln">SkipSelf</span></a><span class="pln">)=&gt;"🌺"&gt;

      </span><span class="com">&lt;!-- With </span><a href="api/core/SkipSelf" class="code-anchor"><span class="com">SkipSelf</span></a><span class="com">, the injector looks to the next injector up the tree --&gt;</span><span class="pln">

      &lt;/#VIEW&gt;
      </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">尽管 <code>&lt;app-child&gt;</code> 提供了🌻（向日葵），但该应用程序渲染了🌺（红色芙蓉），因为 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 导致当前的注入器跳过了自身并寻找其父级。</p><p translation-origin="off">Though <code>&lt;app-child&gt;</code> provides the 🌻 (sunflower), the app renders the 🌺 (red hibiscus) because <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> causes the current injector to skip itself and look to its parent.</p><p translation-result="on">如果现在将 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code>（以及 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> ）添加到了 <code>FlowerService</code> 的 <code>@<a href="api/core/Inject" class="code-anchor">Inject</a></code>，其结果将为 <code>null</code> 。这是因为 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 将搜索的上限限制为 <code>&lt;#VIEW&gt;</code> 。这是在逻辑树中的情况：</p><p translation-origin="off">If you now add <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> (in addition to the <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>) to the <code>@<a href="api/core/Inject" class="code-anchor">Inject</a></code> of the <code>FlowerService</code>, the result will be <code>null</code>. This is because <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> limits the upper bound of the search to the <code>&lt;#VIEW&gt;</code>. Here's the idea in the logical tree:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(FlowerService) flower=&gt;"🌺"&gt; &lt;#VIEW&gt; &lt;!-- end search here with null--&gt; &lt;app-child @Provide(FlowerService="🌻")&gt; &lt;!-- start search here --&gt; &lt;#VIEW @<a href="api/core/Inject" class="code-anchor">Inject</a>(FlowerService, @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>, @<a href="api/core/Host" class="code-anchor">Host</a>, @<a href="api/core/Optional" class="code-anchor">Optional</a>)=&gt;null&gt; &lt;/#VIEW&gt; &lt;/app-parent&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">FlowerService</span><span class="pln">) </span><span class="atn">flower</span><span class="tag">=&gt;</span><span class="pln">"🌺"&gt;
  &lt;#VIEW&gt; </span><span class="com">&lt;!-- end search here with null--&gt;</span><span class="pln">
    </span><span class="tag">&lt;app-child</span><span class="pln"> @</span><span class="atn">Provide</span><span class="pln">(</span><span class="atn">FlowerService</span><span class="pun">=</span><span class="atv">"🌻"</span><span class="pln">)</span><span class="tag">&gt;</span><span class="pln"> </span><span class="com">&lt;!-- start search here --&gt;</span><span class="pln">
      &lt;#VIEW @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(FlowerService, @</span><a href="api/core/SkipSelf" class="code-anchor"><span class="pln">SkipSelf</span></a><span class="pln">, @</span><a href="api/core/Host" class="code-anchor"><span class="pln">Host</span></a><span class="pln">, @</span><a href="api/core/Optional" class="code-anchor"><span class="pln">Optional</span></a><span class="pln">)=&gt;null&gt;
      &lt;/#VIEW&gt;
      </span><span class="tag">&lt;/app-parent&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">在这里，服务及其值是相同的，但是 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 阻止了注入器对 <code>FlowerService</code> 进行任何高于 <code>&lt;#VIEW&gt;</code> 的查找，因此找不到它并返回 <code>null</code> 。</p><p translation-origin="off">Here, the services and their values are the same, but <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> stops the injector from looking any further than the <code>&lt;#VIEW&gt;</code> for <code>FlowerService</code>, so it doesn't find it and returns <code>null</code>.</p><div class="alert is-helpful"><p translation-result="on"><strong>注意：</strong>示例应用程序使用 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> 因此该应用程序不会引发错误，但是其原理是一样的。</p><p translation-origin="off"><strong>Note:</strong> The example app uses <code>@<a href="api/core/Optional" class="code-anchor">Optional</a>()</code> so the app does not throw an error, but the principles are the same.</p></div><h3 id="skipself-and-viewproviders" translation-result="on"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 和 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#skipself-and-viewproviders"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="skipself-and-viewproviders"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> and <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#skipself-and-viewproviders"><i class="material-icons">link</i></a></h3><p translation-result="on">该 <code>&lt;app-child&gt;</code> 目前提供在 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组中提供了值为 🐶（小狗）的 <code>AnimalService</code>。由于注入器只需要查看 <code>&lt;app-child&gt;</code> 的 <code>ElementInjector</code> 中的 <code>AnimalService</code> ，它就不会看到🐳（鲸鱼）。</p><p translation-origin="off">The <code>&lt;app-child&gt;</code> currently provides the <code>AnimalService</code> in the <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array with the value of 🐶 (puppy). Because the injector has only to look at the <code>&lt;app-child&gt;</code>'s <code>ElementInjector</code> for the <code>AnimalService</code>, it never sees the 🐳 (whale).</p><p translation-result="on">就像在 <code>FlowerService</code> 示例中一样，如果将 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 添加到 <code>AnimalService</code> 的构造函数中，则注入器将不在 <code>AnimalService</code> 的当前 <code>&lt;app-child&gt;</code> 的 <code>ElementInjector</code> 中查找 <code>AnimalService</code> 。</p><p translation-origin="off">Just as in the <code>FlowerService</code> example, if you add <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> to the constructor for the <code>AnimalService</code>, the injector won't look in the current <code>&lt;app-child&gt;</code>'s <code>ElementInjector</code> for the <code>AnimalService</code>.</p><code-example language="typescript=" ng-version="9.0.0-rc.11"><div style="display:none">export class ChildComponent { // add @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() constructor(@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() public animal : AnimalService) { } }</div><aio-code><pre class="lang-typescript= prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ChildComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

</span><span class="com">// add @</span><a href="api/core/SkipSelf" class="code-anchor"><span class="com">SkipSelf</span></a><span class="com">()</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/SkipSelf" class="code-anchor"><span class="lit">SkipSelf</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> animal </span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">相反，注入器将从 <code>&lt;app-root&gt;</code> <code>ElementInjector</code> 开始找。请记住， <code>&lt;app-child&gt;</code> 类在 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组中 <code>AnimalService</code> 中提供了🐶（小狗）的值：</p><p translation-origin="off">Instead, the injector will begin at the <code>&lt;app-root&gt;</code> <code>ElementInjector</code>. Remember that the <code>&lt;app-child&gt;</code> class provides the <code>AnimalService</code> in the <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array with a value of 🐶 (puppy):</p><code-example language="ts" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-child', ... <a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a>: [{ provide: AnimalService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🐶' } }] })</div><aio-code><pre class="lang-ts prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-child'</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
  </span><a href="api/core/Component#viewProviders" class="code-anchor"><span class="pln">viewProviders</span></a><span class="pun">:</span><span class="pln">
  </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🐶'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">
</span><span class="pun">})</span></code>
    </pre></aio-code></code-example><p translation-result="on">在 <code>&lt;app-child&gt;</code> 中使用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 的逻辑树是这样的：</p><p translation-origin="off">The logical tree looks like this with <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> in <code>&lt;app-child&gt;</code>:</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService=&gt;"🐳")&gt; &lt;#VIEW&gt;&lt;!-- search begins here --&gt; &lt;app-child&gt; &lt;#VIEW @Provide(AnimalService="🐶") @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService, <a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>=&gt;"🐳")&gt; &lt;!--Add @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a> --&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">AnimalService</span><span class="tag">=&gt;</span><span class="pln">"🐳")&gt;
  &lt;#VIEW&gt;</span><span class="com">&lt;!-- search begins here --&gt;</span><span class="pln">
    </span><span class="tag">&lt;app-child&gt;</span><span class="pln">
      &lt;#VIEW
       @Provide(AnimalService="🐶")
       @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(AnimalService, </span><a href="api/core/SkipSelf" class="code-anchor"><span class="pln">SkipSelf</span></a><span class="pln">=&gt;"🐳")&gt;

       </span><span class="com">&lt;!--Add @</span><a href="api/core/SkipSelf" class="code-anchor"><span class="com">SkipSelf</span></a><span class="com"> --&gt;</span><span class="pln">

      &lt;/#VIEW&gt;
      </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">在 <code>&lt;app-child&gt;</code> 中使用 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>，注入器就会在 <code>&lt;app-root&gt;</code> 的 <code>ElementInjector</code> 中找到 🐳（鲸）。</p><p translation-origin="off">With <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> in the <code>&lt;app-child&gt;</code>, the injector begins its search for the <code>AnimalService</code> in the <code>&lt;app-root&gt;</code> <code>ElementInjector</code> and finds 🐳 (whale).</p><h3 id="host-and-viewproviders" translation-result="on"><code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 和 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#host-and-viewproviders"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="host-and-viewproviders"><code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> and <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code><a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#host-and-viewproviders"><i class="material-icons">link</i></a></h3><p translation-result="on">如果把 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 添加到 <code>AnimalService</code> 的构造函数上，结果就是🐶（小狗），因为注入器会在 <code>&lt;app-child&gt;</code> 的 <code>&lt;#VIEW&gt;</code> 中查找 <code>AnimalService</code> 服务。这里是 <code>&lt;app-child&gt;</code> 类中的 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组和构造函数中的 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> ：</p><p translation-origin="off">If you add <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> to the constructor for <code>AnimalService</code>, the result is 🐶 (puppy) because the injector finds the <code>AnimalService</code> in the <code>&lt;app-child&gt;</code> <code>&lt;#VIEW&gt;</code>. Here is the <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array in the <code>&lt;app-child&gt;</code> class and <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> in the constructor:</p><code-example language="typescript=" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-child', ... <a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a>: [{ provide: AnimalService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🐶' } }] }) export class ChildComponent { constructor(@<a href="api/core/Host" class="code-anchor">Host</a>() public animal : AnimalService) { } }</div><aio-code><pre class="lang-typescript= prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-child'</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
  </span><a href="api/core/Component#viewProviders" class="code-anchor"><span class="pln">viewProviders</span></a><span class="pun">:</span><span class="pln">
  </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🐶'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">

</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ChildComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="lit">@</span><a href="api/core/Host" class="code-anchor"><span class="lit">Host</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> animal </span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 导致注入器开始查找，直到遇到 <code>&lt;#VIEW&gt;</code> 的边缘。</p><p translation-origin="off"><code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> causes the injector to look until it encounters the edge of the <code>&lt;#VIEW&gt;</code>.</p><code-example ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService=&gt;"🐳")&gt; &lt;#VIEW&gt; &lt;app-child&gt; &lt;#VIEW @Provide(AnimalService="🐶") @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService, @<a href="api/core/Host" class="code-anchor">Host</a>=&gt;"🐶")&gt; &lt;!-- @<a href="api/core/Host" class="code-anchor">Host</a> stops search here --&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">AnimalService</span><span class="tag">=&gt;</span><span class="pln">"🐳")&gt;
  &lt;#VIEW&gt;
    </span><span class="tag">&lt;app-child&gt;</span><span class="pln">
      &lt;#VIEW
       @Provide(AnimalService="🐶")
       @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(AnimalService, @</span><a href="api/core/Host" class="code-anchor"><span class="pln">Host</span></a><span class="pln">=&gt;"🐶")&gt; </span><span class="com">&lt;!-- @</span><a href="api/core/Host" class="code-anchor"><span class="com">Host</span></a><span class="com"> stops search here --&gt;</span><span class="pln">
      &lt;/#VIEW&gt;
      </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">将带有第三个动物🦔（刺猬）的 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组添加到 <code>app.component.ts</code> 的 <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 元数据中：</p><p translation-origin="off">Add a <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array with a third animal, 🦔 (hedgehog), to the <code>app.component.ts</code> <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> metadata:</p><code-example language="typescript" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-root', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './app.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: [ './app.component.css' ], <a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a>: [{ provide: AnimalService, <a href="api/core/ValueSansProvider#useValue" class="code-anchor">useValue</a>: { emoji: '🦔' } }] })</div><aio-code><pre class="lang-typescript prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-root'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./app.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="str">'./app.component.css'</span><span class="pln"> </span><span class="pun">],</span><span class="pln">
  </span><a href="api/core/Component#viewProviders" class="code-anchor"><span class="pln">viewProviders</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">,</span><span class="pln"> </span><a href="api/core/ValueSansProvider#useValue" class="code-anchor"><span class="pln">useValue</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> emoji</span><span class="pun">:</span><span class="pln"> </span><span class="str">'🦔'</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}]</span><span class="pln">
</span><span class="pun">})</span></code>
    </pre></aio-code></code-example><p translation-result="on">接下来，同时把 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 和 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 加在 <code>child.component.ts</code> 中 <code>AnimalService</code> 的构造函数中。这是 <code>&lt;app-child&gt;</code> 构造函数中的 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 和 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>：</p><p translation-origin="off">Next, add <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> along with <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> to the constructor for the <code>Animal Service</code> in <code>child.component.ts</code>. Here are <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> and <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> in the <code>&lt;app-child&gt;</code> constructor :</p><code-example language="ts" ng-version="9.0.0-rc.11"><div style="display:none">export class ChildComponent { constructor( @<a href="api/core/Host" class="code-anchor">Host</a>() @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() public animal : AnimalService) { } }</div><aio-code><pre class="lang-ts prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ChildComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">
  </span><span class="lit">@</span><a href="api/core/Host" class="code-anchor"><span class="lit">Host</span></a><span class="pun">()</span><span class="pln"> </span><span class="lit">@</span><a href="api/core/SkipSelf" class="code-anchor"><span class="lit">SkipSelf</span></a><span class="pun">()</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> animal </span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimalService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">将 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 和 <code><a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 应用于 <code>providers</code> 数组中的 <code>FlowerService</code>，结果为 <code>null</code>，因为 <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 会在 <code>&lt;app-child&gt;</code> 的注入器中开始搜索，但是 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 要求它在 <code>&lt;#VIEW&gt;</code> 停止搜索 —— 没有 <code>FlowerService</code> 。在逻辑树中，您可以看到 <code>FlowerService</code> 在 <code>&lt;app-child&gt;</code> 中可见，而在 <code>&lt;#VIEW&gt;</code> 中不可见。</p><p translation-origin="off">When <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> and <code><a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> were applied to the <code>FlowerService</code>, which is in the <code>providers</code> array, the result was <code>null</code> because <code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> starts its search in the <code>&lt;app-child&gt;</code> injector, but <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> stops searching at <code>&lt;#VIEW&gt;</code>—where there is no <code>FlowerService</code>. In the logical tree, you can see that the <code>FlowerService</code> is visible in <code>&lt;app-child&gt;</code>, not its <code>&lt;#VIEW&gt;</code>.</p><p translation-result="on">不过，提供在 <code>AppComponent</code> 的 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组中的 <code>AnimalService</code> ，是可见的。</p><p translation-origin="off">However, the <code>AnimalService</code>, which is provided in the <code>AppComponent</code> <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array, is visible.</p><p translation-result="on">逻辑树表示法说明了为何如此：</p><p translation-origin="off">The logical tree representation shows why this is:</p><code-example language="html" ng-version="9.0.0-rc.11"><div style="display:none">&lt;app-root @<a href="api/core/NgModule" class="code-anchor">NgModule</a>(AppModule) @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService=&gt;"🐳")&gt; &lt;#VIEW @Provide(AnimalService="🦔") @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService, @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>, @<a href="api/core/Host" class="code-anchor">Host</a>, @<a href="api/core/Optional" class="code-anchor">Optional</a>)=&gt;"🦔"&gt; &lt;!-- ^^@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>() starts here, @<a href="api/core/Host" class="code-anchor">Host</a>() stops here^^ --&gt; &lt;app-child&gt; &lt;#VIEW @Provide(AnimalService="🐶") @<a href="api/core/Inject" class="code-anchor">Inject</a>(AnimalService, @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>, @<a href="api/core/Host" class="code-anchor">Host</a>, @<a href="api/core/Optional" class="code-anchor">Optional</a>)=&gt;"🐶"&gt; &lt;!-- Add @<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a> ^^--&gt; &lt;/#VIEW&gt; &lt;/app-child&gt; &lt;/#VIEW&gt; &lt;/app-root&gt;</div><aio-code><pre class="lang-html prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;app-root</span><span class="pln"> @</span><a href="api/core/NgModule" class="code-anchor"><span class="atn">NgModule</span></a><span class="pln">(</span><span class="atn">AppModule</span><span class="pln">)
        @</span><a href="api/core/Inject" class="code-anchor"><span class="atn">Inject</span></a><span class="pln">(</span><span class="atn">AnimalService</span><span class="tag">=&gt;</span><span class="pln">"🐳")&gt;
  &lt;#VIEW @Provide(AnimalService="🦔")
         @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(AnimalService, @</span><a href="api/core/SkipSelf" class="code-anchor"><span class="pln">SkipSelf</span></a><span class="pln">, @</span><a href="api/core/Host" class="code-anchor"><span class="pln">Host</span></a><span class="pln">, @</span><a href="api/core/Optional" class="code-anchor"><span class="pln">Optional</span></a><span class="pln">)=&gt;"🦔"&gt;

    </span><span class="com">&lt;!-- ^^@</span><a href="api/core/SkipSelf" class="code-anchor"><span class="com">SkipSelf</span></a><span class="com">() starts here,  @</span><a href="api/core/Host" class="code-anchor"><span class="com">Host</span></a><span class="com">() stops here^^ --&gt;</span><span class="pln">

    </span><span class="tag">&lt;app-child&gt;</span><span class="pln">
      &lt;#VIEW @Provide(AnimalService="🐶")
             @</span><a href="api/core/Inject" class="code-anchor"><span class="pln">Inject</span></a><span class="pln">(AnimalService, @</span><a href="api/core/SkipSelf" class="code-anchor"><span class="pln">SkipSelf</span></a><span class="pln">, @</span><a href="api/core/Host" class="code-anchor"><span class="pln">Host</span></a><span class="pln">, @</span><a href="api/core/Optional" class="code-anchor"><span class="pln">Optional</span></a><span class="pln">)=&gt;"🐶"&gt;

               </span><span class="com">&lt;!-- Add @</span><a href="api/core/SkipSelf" class="code-anchor"><span class="com">SkipSelf</span></a><span class="com"> ^^--&gt;</span><span class="pln">

      &lt;/#VIEW&gt;
      </span><span class="tag">&lt;/app-child&gt;</span><span class="pln">
  &lt;/#VIEW&gt;
</span><span class="tag">&lt;/app-root&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code> 导致注入器从 <code>&lt;app-root&gt;</code> 而不是 <code>&lt;app-child&gt;</code> 处开始对 <code>AnimalService</code> 进行搜索，而 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 会在 <code>&lt;app-root&gt;</code> 的 <code>&lt;#VIEW&gt;</code> 处停止搜索。 由于 <code>AnimalService</code> 是通过 <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> 数组提供的，因此注入程序会在 <code>&lt;#VIEW&gt;</code> 找到🦔（刺猬）。</p><p translation-origin="off"><code>@<a href="api/core/SkipSelf" class="code-anchor">SkipSelf</a>()</code>, causes the injector to start its search for the <code>AnimalService</code> at the <code>&lt;app-root&gt;</code>, not the <code>&lt;app-child&gt;</code>, where the request originates, and <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> stops the search at the <code>&lt;app-root&gt;</code> <code>&lt;#VIEW&gt;</code>. Since <code>AnimalService</code> is provided via the <code><a href="api/core/Component#viewProviders" class="code-anchor">viewProviders</a></code> array, the injector finds 🦔 (hedgehog) in the <code>&lt;#VIEW&gt;</code>.</p><a id="component-injectors"></a><h2 id="elementinjector-use-case-examples" translation-result="on"><code>ElementInjector</code> 用例示例<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#elementinjector-use-case-examples"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="elementinjector-use-case-examples"><code>ElementInjector</code> use case examples<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#elementinjector-use-case-examples"><i class="material-icons">link</i></a></h2><p translation-result="on">在不同级别配置一个或多个提供者的能力开辟了很有用的可能性。要查看正在运行的应用中的以下情况，请参阅<live-example ng-version="9.0.0-rc.11"><span style="display:none">英雄示例</span><span><span class="ng-star-inserted"><a target="_blank" title="英雄示例" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html">英雄示例</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>。</p><p translation-origin="off">The ability to configure one or more providers at different levels opens up useful possibilities. For a look at the following scenarios in a working app, see the<live-example ng-version="9.0.0-rc.11"><span style="display:none">heroes use case examples</span><span><span class="ng-star-inserted"><a target="_blank" title="heroes use case examples" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html">heroes use case examples</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>.</p><h3 id="scenario-service-isolation" translation-result="on">场景：服务隔离<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-service-isolation"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="scenario-service-isolation">Scenario: service isolation<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-service-isolation"><i class="material-icons">link</i></a></h3><p translation-result="on">出于架构方面的考虑，可能会让你决定把一个服务限制到只能在它所属的那个应用域中访问。 比如，这个例子中包括一个用于显示反派列表的 <code>VillainsListComponent</code>，它会从 <code>VillainsService</code> 中获得反派列表数据。</p><p translation-origin="off">Architectural reasons may lead you to restrict access to a service to the application domain where it belongs. For example, the guide sample includes a <code>VillainsListComponent</code> that displays a list of villains. It gets those villains from a <code>VillainsService</code>.</p><p translation-result="on">如果你在根模块 <code>AppModule</code> 中（也就是你注册 <code>HeroesService</code> 的地方）提供 <code>VillainsService</code>，就会让应用中的任何地方都能访问到 <code>VillainsService</code>，包括针对英雄的工作流。如果你稍后修改了 <code>VillainsService</code>，就可能破坏了英雄组件中的某些地方。在根模块 <code>AppModule</code> 中提供该服务将会引入此风险。</p><p translation-origin="off">If you provided <code>VillainsService</code> in the root <code>AppModule</code> (where you registered the <code>HeroesService</code>), that would make the <code>VillainsService</code> visible everywhere in the application, including the <em>Hero</em> workflows. If you later modified the <code>VillainsService</code>, you could break something in a hero component somewhere.</p><p translation-result="on">该怎么做呢？你可以在 <code>VillainsListComponent</code> 的 <code>providers</code> 元数据中提供 <code>VillainsService</code>，就像这样：</p><p translation-origin="off">Instead, you can provide the <code>VillainsService</code> in the <code>providers</code> metadata of the <code>VillainsListComponent</code> like this:</p><code-example path="hierarchical-dependency-injection/src/app/villains-list.component.ts" header="src/app/villains-list.component.ts (metadata)" region="metadata" ng-version="9.0.0-rc.11"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-villains-list', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './villains-list.component.html', providers: [ VillainsService ] })</div><header class="ng-star-inserted">src/app/villains-list.component.ts (metadata)</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from src/app/villains-list.component.ts (metadata)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-villains-list'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./villains-list.component.html'</span><span class="pun">,</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">VillainsService</span><span class="pln"> </span><span class="pun">]</span><span class="pln">
</span><span class="pun">})</span></code>
    </pre></aio-code></code-example><p translation-result="on">在 <code>VillainsListComponent</code> 的元数据中而不是其它地方提供 <code>VillainsService</code> 服务，该服务就会只在 <code>VillainsListComponent</code> 及其子组件树中可用。</p><p translation-origin="off">By providing <code>VillainsService</code> in the <code>VillainsListComponent</code> metadata and nowhere else, the service becomes available only in the <code>VillainsListComponent</code> and its sub-component tree.</p><p translation-result="on"><code>VillainService</code> 对于 <code>VillainsListComponent</code> 来说是单例的，因为它就是在这里声明的。只要 <code>VillainsListComponent</code> 没有销毁，它就始终是 <code>VillainService</code> 的同一个实例。但是对于 <code>VillainsListComponent</code> 的多个实例，每个 <code>VillainsListComponent</code> 的实例都会有自己的 <code>VillainService</code> 实例。</p><p translation-origin="off"><code>VillainService</code> is a singleton with respect to <code>VillainsListComponent</code> because that is where it is declared. As long as <code>VillainsListComponent</code> does not get destroyed it will be the same instance of <code>VillainService</code> but if there are multilple instances of <code>VillainsListComponent</code>, then each instance of <code>VillainsListComponent</code> will have its own instance of <code>VillainService</code>.</p><h3 id="scenario-multiple-edit-sessions" translation-result="on">场景：多重编辑会话<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="scenario-multiple-edit-sessions">Scenario: multiple edit sessions<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions"><i class="material-icons">link</i></a></h3><p translation-result="on">很多应用允许用户同时进行多个任务。 比如，在纳税申报应用中，申报人可以打开多个报税单，随时可能从一个切换到另一个。</p><p translation-origin="off">Many applications allow users to work on several open tasks at the same time. For example, in a tax preparation application, the preparer could be working on several tax returns, switching from one to the other throughout the day.</p><p translation-result="on">本章要示范的场景仍然是基于《英雄指南》的。 想象一个外层的 <code>HeroListComponent</code>，它显示一个超级英雄的列表。</p><p translation-origin="off">This guide demonstrates that scenario with an example in the Tour of Heroes theme. Imagine an outer <code>HeroListComponent</code> that displays a list of super heroes.</p><p translation-result="on">要打开一个英雄的报税单，申报者点击英雄名，它就会打开一个组件来编辑那个申报单。 每个选中的申报单都会在自己的组件中打开，并且可以同时打开多个申报单。</p><p translation-origin="off">To open a hero's tax return, the preparer clicks on a hero name, which opens a component for editing that return. Each selected hero tax return opens in its own component and multiple returns can be open at the same time.</p><p translation-result="on">每个报税单组件都有下列特征：</p><p translation-origin="off">Each tax return component has the following characteristics:</p><ul><li><p translation-result="on">属于它自己的报税单会话。</p><p translation-origin="off">Is its own tax return editing session.</p></li><li><p translation-result="on">可以修改一个报税单，而不会影响另一个组件中的申报单。</p><p translation-origin="off">Can change a tax return without affecting a return in another component.</p></li><li><p translation-result="on">能把所做的修改保存到它的报税单中，或者放弃它们。</p><p translation-origin="off">Has the ability to save the changes to its tax return or cancel them.</p></li></ul><div class="lightbox"><img src="generated/images/guide/dependency-injection/hid-heroes-anim.gif" alt="Heroes in action" width="500" height="384"></div><p translation-result="on">假设 <code>HeroTaxReturnComponent</code> 还有一些管理并还原这些更改的逻辑。 这对于简单的报税单来说是很容易的。 不过，在现实世界中，报税单的数据模型非常复杂，对这些修改的管理可能不得不投机取巧。 你可以把这种管理任务委托给一个辅助服务，就像这个例子中所做的。</p><p translation-origin="off">Suppose that the <code>HeroTaxReturnComponent</code> had logic to manage and restore changes. That would be a pretty easy task for a simple hero tax return. In the real world, with a rich tax return data model, the change management would be tricky. You could delegate that management to a helper service, as this example does.</p><p translation-result="on">报税单服务 <code>HeroTaxReturnService</code> 缓存了单条 <code>HeroTaxReturn</code>，用于跟踪那个申报单的变更，并且可以保存或还原它。 它还委托给了全应用级的单例服务 <code>HeroService</code>，它是通过依赖注入机制取得的。</p><p translation-origin="off">The <code>HeroTaxReturnService</code> caches a single <code>HeroTaxReturn</code>, tracks changes to that return, and can save or restore it. It also delegates to the application-wide singleton <code>HeroService</code>, which it gets by injection.</p><code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.service.ts" header="src/app/hero-tax-return.service.ts" ng-version="9.0.0-rc.11"><div style="display:none">import { <a href="api/core/Injectable" class="code-anchor">Injectable</a> } from '@angular/core'; import { HeroTaxReturn } from './hero'; import { HeroesService } from './heroes.service'; @<a href="api/core/Injectable" class="code-anchor">Injectable</a>() export class HeroTaxReturnService { private currentTaxReturn: HeroTaxReturn; private originalTaxReturn: HeroTaxReturn; constructor(private heroService: HeroesService) { } set taxReturn (htr: HeroTaxReturn) { this.originalTaxReturn = htr; this.currentTaxReturn = htr.clone(); } get taxReturn (): HeroTaxReturn { return this.currentTaxReturn; } restoreTaxReturn() { this.taxReturn = this.originalTaxReturn; } saveTaxReturn() { this.taxReturn = this.currentTaxReturn; this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe(); } }</div><header class="ng-star-inserted">src/app/hero-tax-return.service.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from src/app/hero-tax-return.service.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Injectable" class="code-anchor"><span class="typ">Injectable</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln">    </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroesService</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./heroes.service'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Injectable" class="code-anchor"><span class="lit">Injectable</span></a><span class="pun">()</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">private</span><span class="pln"> currentTaxReturn</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">private</span><span class="pln"> originalTaxReturn</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">;</span><span class="pln">

  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">private</span><span class="pln"> heroService</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroesService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

  </span><span class="kwd">set</span><span class="pln"> taxReturn </span><span class="pun">(</span><span class="pln">htr</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">originalTaxReturn </span><span class="pun">=</span><span class="pln"> htr</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn  </span><span class="pun">=</span><span class="pln"> htr</span><span class="pun">.</span><span class="pln">clone</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="kwd">get</span><span class="pln"> taxReturn </span><span class="pun">():</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  restoreTaxReturn</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">taxReturn </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">originalTaxReturn</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  saveTaxReturn</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">taxReturn </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroService</span><span class="pun">.</span><span class="pln">saveTaxReturn</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn</span><span class="pun">).</span><span class="pln">subscribe</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">下面是正在使用 <code>HeroTaxReturnService</code> 的 <code>HeroTaxReturnComponent</code> 组件。</p><p translation-origin="off">Here is the <code>HeroTaxReturnComponent</code> that makes use of <code>HeroTaxReturnService</code>.</p><code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" header="src/app/hero-tax-return.component.ts" ng-version="9.0.0-rc.11"><div style="display:none">import { <a href="api/core/Component" class="code-anchor">Component</a>, <a href="api/core/EventEmitter" class="code-anchor">EventEmitter</a>, <a href="api/core/Input" class="code-anchor">Input</a>, <a href="api/core/Output" class="code-anchor">Output</a> } from '@angular/core'; import { HeroTaxReturn } from './hero'; import { HeroTaxReturnService } from './hero-tax-return.service'; @<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-hero-tax-return', <a href="api/core/Component#templateUrl" class="code-anchor">templateUrl</a>: './hero-tax-return.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: [ './hero-tax-return.component.css' ], providers: [ HeroTaxReturnService ] }) export class HeroTaxReturnComponent { <a href="api/common/http/HttpErrorResponse#message" class="code-anchor">message</a> = ''; @<a href="api/core/Output" class="code-anchor">Output</a>() close = new <a href="api/core/EventEmitter" class="code-anchor">EventEmitter</a>&lt;void&gt;(); get taxReturn(): HeroTaxReturn { return this.heroTaxReturnService.taxReturn; } @<a href="api/core/Input" class="code-anchor">Input</a>() set taxReturn (htr: HeroTaxReturn) { this.heroTaxReturnService.taxReturn = htr; } constructor(private heroTaxReturnService: HeroTaxReturnService) { } onCanceled() { this.flashMessage('Canceled'); this.heroTaxReturnService.restoreTaxReturn(); }; onClose() { this.close.emit(); }; onSaved() { this.flashMessage('Saved'); this.heroTaxReturnService.saveTaxReturn(); } flashMessage(msg: string) { this.message = msg; setTimeout(() =&gt; this.message = '', 500); } }</div><header class="ng-star-inserted">src/app/hero-tax-return.component.ts</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from src/app/hero-tax-return.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Component" class="code-anchor"><span class="typ">Component</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/EventEmitter" class="code-anchor"><span class="typ">EventEmitter</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/Input" class="code-anchor"><span class="typ">Input</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/Output" class="code-anchor"><span class="typ">Output</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">}</span><span class="pln">        </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero-tax-return.service'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-hero-tax-return'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#templateUrl" class="code-anchor"><span class="pln">templateUrl</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'./hero-tax-return.component.html'</span><span class="pun">,</span><span class="pln">
  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="str">'./hero-tax-return.component.css'</span><span class="pln"> </span><span class="pun">],</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">]</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HeroTaxReturnComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><a href="api/common/http/HttpErrorResponse#message" class="code-anchor"><span class="pln">message</span></a><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">''</span><span class="pun">;</span><span class="pln">

  </span><span class="lit">@</span><a href="api/core/Output" class="code-anchor"><span class="lit">Output</span></a><span class="pun">()</span><span class="pln"> close </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><a href="api/core/EventEmitter" class="code-anchor"><span class="typ">EventEmitter</span></a><span class="str">&lt;void&gt;</span><span class="pun">();</span><span class="pln">

  </span><span class="kwd">get</span><span class="pln"> taxReturn</span><span class="pun">():</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">taxReturn</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">()</span><span class="pln">
  </span><span class="kwd">set</span><span class="pln"> taxReturn </span><span class="pun">(</span><span class="pln">htr</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">taxReturn </span><span class="pun">=</span><span class="pln"> htr</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">private</span><span class="pln"> heroTaxReturnService</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

  onCanceled</span><span class="pun">()</span><span class="pln">  </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">flashMessage</span><span class="pun">(</span><span class="str">'Canceled'</span><span class="pun">);</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">restoreTaxReturn</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">};</span><span class="pln">

  onClose</span><span class="pun">()</span><span class="pln">  </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">close</span><span class="pun">.</span><span class="pln">emit</span><span class="pun">();</span><span class="pln"> </span><span class="pun">};</span><span class="pln">

  onSaved</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">flashMessage</span><span class="pun">(</span><span class="str">'Saved'</span><span class="pun">);</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">saveTaxReturn</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  flashMessage</span><span class="pun">(</span><span class="pln">msg</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">message </span><span class="pun">=</span><span class="pln"> msg</span><span class="pun">;</span><span class="pln">
    setTimeout</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">message </span><span class="pun">=</span><span class="pln"> </span><span class="str">''</span><span class="pun">,</span><span class="pln"> </span><span class="lit">500</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">通过 <code>@<a href="api/core/Input" class="code-anchor">Input</a>()</code> 属性可以得到<em>要编辑的报税单</em>，这个属性被实现成了读取器（getter）和设置器（setter）。 设置器根据传进来的报税单初始化了组件自己的 <code>HeroTaxReturnService</code> 实例。 读取器总是返回该服务所存英雄的当前状态。 组件也会请求该服务来保存或还原这个报税单。</p><p translation-origin="off">The <em>tax-return-to-edit</em> arrives via the <code>@<a href="api/core/Input" class="code-anchor">Input</a>()</code> property, which is implemented with getters and setters. The setter initializes the component's own instance of the <code>HeroTaxReturnService</code> with the incoming return. The getter always returns what that service says is the current state of the hero. The component also asks the service to save and restore this tax return.</p><p translation-result="on">但如果该服务是一个全应用范围的单例就不行了。 每个组件就都会共享同一个服务实例，每个组件也都会覆盖属于其他英雄的报税单。</p><p translation-origin="off">This won't work if the service is an application-wide singleton. Every component would share the same service instance, and each component would overwrite the tax return that belonged to another hero.</p><p translation-result="on">要防止这一点，就要在 <code>HeroTaxReturnComponent</code> 元数据的 <code>providers</code> 属性中配置组件级的注入器，来提供该服务。</p><p translation-origin="off">To prevent this, configure the component-level injector of <code>HeroTaxReturnComponent</code> to provide the service, using the <code>providers</code> property in the component metadata.</p><code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" header="src/app/hero-tax-return.component.ts (providers)" region="providers" ng-version="9.0.0-rc.11"><div style="display:none">providers: [ HeroTaxReturnService ]</div><header class="ng-star-inserted">src/app/hero-tax-return.component.ts (providers)</header><aio-code class="headed-code"><pre class="lang- prettyprint">      <button title="Copy code snippet" class="material-icons copy-button no-print ng-star-inserted" aria-label="Copy code snippet from src/app/hero-tax-return.component.ts (providers)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="pln">providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">]</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>HeroTaxReturnComponent</code> 有它自己的 <code>HeroTaxReturnService</code> 提供者。 回忆一下，每个组件的<em>实例</em>都有它自己的注入器。 在组件级提供服务可以确保组件的<em>每个</em>实例都得到一个自己的、私有的服务实例，而报税单也不会再被意外覆盖了。</p><p translation-origin="off">The <code>HeroTaxReturnComponent</code> has its own provider of the <code>HeroTaxReturnService</code>. Recall that every component <em>instance</em> has its own injector. Providing the service at the component level ensures that <em>every</em> instance of the component gets its own, private instance of the service, and no tax return gets overwritten.</p><div class="alert is-helpful"><p translation-result="on">该场景代码中的其它部分依赖另一些 Angular 的特性和技术，你将会在本文档的其它章节学到。 你可以到<live-example ng-version="9.0.0-rc.11"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" title="现场演练" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html">现场演练</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>查看代码和下载它。</p><p translation-origin="off">The rest of the scenario code relies on other Angular features and techniques that you can learn about elsewhere in the documentation. You can review it and download it from the<live-example ng-version="9.0.0-rc.11"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" title="现场演练" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html">现场演练</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>.</p></div><h3 id="scenario-specialized-providers" translation-result="on">场景：专门的提供者<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-specialized-providers"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="scenario-specialized-providers">Scenario: specialized providers<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-specialized-providers"><i class="material-icons">link</i></a></h3><p translation-result="on">在其它层级重新提供服务的另一个理由，是在组件树的深层中把该服务替换为一个<em>更专门化的</em>实现。</p><p translation-origin="off">Another reason to re-provide a service at another level is to substitute a <em>more specialized</em> implementation of that service, deeper in the component tree.</p><p translation-result="on">考虑一个依赖于一系列服务的 Car 组件。 假设你在根注入器（代号 A）中配置了<em>通用的</em>提供者：<code>CarService</code>、<code>EngineService</code> 和 <code>TiresService</code>。</p><p translation-origin="off">Consider a Car component that depends on several services. Suppose you configured the root injector (marked as A) with <em>generic</em> providers for <code>CarService</code>, <code>EngineService</code> and <code>TiresService</code>.</p><p translation-result="on">你创建了一个车辆组件（A），它显示一个从另外三个通用服务构造出的车辆。</p><p translation-origin="off">You create a car component (A) that displays a car constructed from these three generic services.</p><p translation-result="on">然后，你创建一个子组件（B），它为 <code>CarService</code> 和 <code>EngineService</code> 定义了自己<em>特有的</em>提供者，它们具有适用于组件 B 的特有能力。</p><p translation-origin="off">Then you create a child component (B) that defines its own, <em>specialized</em> providers for <code>CarService</code> and <code>EngineService</code> that have special capabilities suitable for whatever is going on in component (B).</p><p translation-result="on">组件 B 是另一个组件 C 的父组件，而组件 C 又定义了自己的，<em>更特殊的</em><code>CarService</code> 提供者。</p><p translation-origin="off">Component (B) is the parent of another component (C) that defines its own, even <em>more specialized</em> provider for <code>CarService</code>.</p><div class="lightbox"><img src="generated/images/guide/dependency-injection/car-components.png" alt="car components" width="338" height="201"></div><p translation-result="on">在幕后，每个组件都有自己的注入器，这个注入器带有为组件本身准备的 0 个、1 个或多个提供者。</p><p translation-origin="off">Behind the scenes, each component sets up its own injector with zero, one, or more providers defined for that component itself.</p><p translation-result="on">当你在最深层的组件 C 解析 <code>Car</code> 的实例时，它使用注入器 C 解析生成了一个 <code>Car</code> 的实例，使用注入器 B 解析了 <code>Engine</code>，而 <code>Tires</code> 则是由根注入器 A 解析的。</p><p translation-origin="off">When you resolve an instance of <code>Car</code> at the deepest component (C), its injector produces an instance of <code>Car</code> resolved by injector (C) with an <code>Engine</code> resolved by injector (B) and <code>Tires</code> resolved by the root injector (A).</p><div class="lightbox"><img src="generated/images/guide/dependency-injection/injector-tree.png" alt="car injector tree" width="600" height="248"></div><hr><h2 id="more-on-dependency-injection" translation-result="on">关于依赖注入的更多知识<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#more-on-dependency-injection"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="more-on-dependency-injection">More on dependency injection<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#more-on-dependency-injection"><i class="material-icons">link</i></a></h2><p translation-result="on">要了解关于 Angular 依赖注入的更多信息，参见 <a href="guide/dependency-injection-providers">DI 提供者</a>和 <a href="guide/dependency-injection-in-action">DI 实战</a> 两章。</p><p translation-origin="off">For more information on Angular dependency injection, see the <a href="guide/dependency-injection-providers">DI Providers</a> and <a href="guide/dependency-injection-in-action">DI in Action</a> guides.</p></div></div></aio-doc-viewer></main></mat-sidenav-content></mat-sidenav-container><div class="toc-container no-print ng-star-inserted"><aio-lazy-ce selector="aio-toc"><aio-toc ng-version="9.0.0-rc.11"><div class="toc-inner no-print collapsed ng-star-inserted"><ul class="toc-list"><li class="h1 ng-star-inserted active" title="多级注入器"><a href="guide/hierarchical-dependency-injection#hierarchical-injectors">多级注入器</a></li><li class="h2 ng-star-inserted" title="两个注入器层次结构"><a href="guide/hierarchical-dependency-injection#two-injector-hierarchies">两个注入器层次结构</a></li><li class="h3 ng-star-inserted" title="ModuleInjector"><a href="guide/hierarchical-dependency-injection#moduleinjector"><code>ModuleInjector</code></a></li><li class="h3 ng-star-inserted" title="ElementInjector"><a href="guide/hierarchical-dependency-injection#elementinjector"><code>ElementInjector</code></a></li><li class="h2 ng-star-inserted" title="解析规则"><a href="guide/hierarchical-dependency-injection#resolution-rules">解析规则</a></li><li class="h2 ng-star-inserted" title="解析修饰符"><a href="guide/hierarchical-dependency-injection#resolution-modifiers">解析修饰符</a></li><li class="h3 ng-star-inserted" title="修饰符的类型"><a href="guide/hierarchical-dependency-injection#types-of-modifiers">修饰符的类型</a></li><li class="h3 ng-star-inserted" title="@Optional()"><a href="guide/hierarchical-dependency-injection#optional"><code>@Optional()</code></a></li><li class="h3 ng-star-inserted" title="@Self()"><a href="guide/hierarchical-dependency-injection#self"><code>@Self()</code></a></li><li class="h3 ng-star-inserted" title="@SkipSelf()"><a href="guide/hierarchical-dependency-injection#skipself"><code>@SkipSelf()</code></a></li><li class="h3 ng-star-inserted" title="@Host()"><a href="guide/hierarchical-dependency-injection#host"><code>@Host()</code></a></li><li class="h2 ng-star-inserted" title="模板的逻辑结构"><a href="guide/hierarchical-dependency-injection#logical-structure-of-the-template">模板的逻辑结构</a></li><li class="h2 ng-star-inserted" title="在 @Component() 中提供服务"><a href="guide/hierarchical-dependency-injection#providing-services-in-component">在 <code>@Component()</code> 中提供服务</a></li><li class="h3 ng-star-inserted" title="应用程序结构示例"><a href="guide/hierarchical-dependency-injection#example-app-structure">应用程序结构示例</a></li><li class="h3 ng-star-inserted" title="使用 providers 数组"><a href="guide/hierarchical-dependency-injection#using-the-providers-array">使用 <code>providers</code> 数组</a></li><li class="h3 ng-star-inserted" title="使用 viewProviders 数组"><a href="guide/hierarchical-dependency-injection#using-the-viewproviders-array">使用 <code>viewProviders</code> 数组</a></li><li class="h3 ng-star-inserted" title="providers 与 viewProviders"><a href="guide/hierarchical-dependency-injection#providers-vs-viewproviders"><code>providers</code> 与 <code>viewProviders</code></a></li><li class="h2 ng-star-inserted" title="修改服务可见性"><a href="guide/hierarchical-dependency-injection#modifying-service-visibility">修改服务可见性</a></li><li class="h3 ng-star-inserted" title="提供者令牌的可见性"><a href="guide/hierarchical-dependency-injection#visibility-of-provided-tokens">提供者令牌的可见性</a></li><li class="h3 ng-star-inserted" title="@SkipSelf() 和 viewProviders"><a href="guide/hierarchical-dependency-injection#skipself-and-viewproviders"><code>@SkipSelf()</code> 和 <code>viewProviders</code></a></li><li class="h3 ng-star-inserted" title="@Host() 和 viewProviders"><a href="guide/hierarchical-dependency-injection#host-and-viewproviders"><code>@Host()</code> 和 <code>viewProviders</code></a></li><li class="h2 ng-star-inserted" title="ElementInjector 用例示例"><a href="guide/hierarchical-dependency-injection#elementinjector-use-case-examples"><code>ElementInjector</code> 用例示例</a></li><li class="h3 ng-star-inserted" title="场景：服务隔离"><a href="guide/hierarchical-dependency-injection#scenario-service-isolation">场景：服务隔离</a></li><li class="h3 ng-star-inserted" title="场景：多重编辑会话"><a href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions">场景：多重编辑会话</a></li><li class="h3 ng-star-inserted" title="场景：专门的提供者"><a href="guide/hierarchical-dependency-injection#scenario-specialized-providers">场景：专门的提供者</a></li><li class="h2 ng-star-inserted" title="关于依赖注入的更多知识"><a href="guide/hierarchical-dependency-injection#more-on-dependency-injection">关于依赖注入的更多知识</a></li></ul></div></aio-toc></aio-lazy-ce></div><footer class="no-print"><aio-footer><div class="grid-fluid"><div class="footer-block ng-star-inserted"><h3>资源</h3><ul><li class="ng-star-inserted"><a class="link" href="about" title="Angular 贡献者。">关于</a></li><li class="ng-star-inserted"><a class="link" href="resources" title="网络上的 Angular 工具、培训、博客等">资源列表</a></li><li class="ng-star-inserted"><a class="link" href="presskit" title="我们的联系方式、LOGO 和品牌">宣传资料</a></li><li class="ng-star-inserted"><a class="link" href="https://blog.angular.io/" title="Angular 官方博客">博客</a></li><li class="ng-star-inserted"><a class="link" href="analytics" title="Angular 使用情况分析">使用情况分析</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>帮助</h3><ul><li class="ng-star-inserted"><a class="link" href="https://stackoverflow.com/questions/tagged/angular" title="Stack Overflow: 这里的社区会回答你关于 Angular 的技术问题">Stack Overflow</a></li><li class="ng-star-inserted"><a class="link" href="https://gitter.im/angular/angular" title="和老鸟聊 Angular">Gitter</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/angular/issues" title="在 github 上报告问题和建议。">报告问题</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md" title="让我们彼此尊重">行为规范</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>社区</h3><ul><li class="ng-star-inserted"><a class="link" href="events" title="Angular events around the world.">活动</a></li><li class="ng-star-inserted"><a class="link" href="http://www.meetup.com/topics/angularjs/" title="参加聚会，向别的开发人员学习">聚会</a></li><li class="ng-star-inserted"><a class="link" href="https://twitter.com/angular" title="Twitter">Twitter</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/angular" title="GitHub">GitHub</a></li><li class="ng-star-inserted"><a class="link" href="contribute" title="向 Angular 做贡献">做贡献</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>多语言</h3><ul><li class="ng-star-inserted"><a class="link" href="https://angular.io/" title="English Version.">English Version</a></li><li class="ng-star-inserted"><a class="link" href="https://angular.tw/" title="正體中文版">正體中文版</a></li><li class="ng-star-inserted"><a class="link" href="https://angular.jp/" title="日本語版">日本語版</a></li><li class="ng-star-inserted"><a class="link" href="https://angular.kr/" title="한국어">한국어</a></li></ul></div></div><p>Super-powered by Google ©2010-2020. 代码授权方式：<a href="license" title="License text">MIT-style License</a>. 文档授权方式：<a href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.</p><p>当前版本：9.0.1-build.109+sha.7a49faba.</p></aio-footer></footer><div class="cdk-visually-hidden ng-star-inserted"><mat-icon role="img" class="mat-icon notranslate material-icons mat-icon-no-color" aria-hidden="true">&nbsp;</mat-icon></div></aio-shell><noscript><div class="background-sky hero"></div><section id="intro" style="text-shadow:1px 1px #1976d2"><div class="hero-logo"><img src="assets/images/logos/angular/angular.svg" width="250" height="250" alt="Angular"></div><div class="homepage-container"><div class="hero-headline">一套框架，多种平台<br>移动 &amp; 桌面</div></div></section><h2 style="color:red;margin-top:40px;position:relative;text-align:center;text-shadow:1px 1px #fafafa"><b><i>该网站需要浏览器支持 JavaScript</i></b></h2></noscript><script src="runtime-es2015.811b066977719df5af39.js" type="module"></script><script src="runtime-es5.811b066977719df5af39.js" nomodule="" defer=""></script><script src="polyfills-es5.1494ca908613f3429457.js" nomodule="" defer=""></script><script src="polyfills-es2015.9057a05c650bf60ecbf4.js" type="module"></script><script src="main-es2015.4e9aa34b562bab1382ab.js" type="module"></script><script src="main-es5.4e9aa34b562bab1382ab.js" nomodule="" defer=""></script><div class="cdk-live-announcer-element cdk-visually-hidden" aria-atomic="true" aria-live="polite"></div></body></html>